Public/Start-PdqDeployment.ps1
<#
.SYNOPSIS A wrapper for "PDQDeploy.exe Deploy" that adds extra features. .INPUTS None. .OUTPUTS System.Management.Automation.PSCustomObject System.Object[] .EXAMPLE Start-PdqDeployment -Package 'Google Chrome Enterprise' -IgnoreVersion -Target 'CEO-PC' Deploy Chrome to CEO-PC. .EXAMPLE Start-PdqDeployment -Folder 'AutoCAD' -Collection 'AutoCAD (Not Installed)' -Wait Deploy all of the packages in the AutoCAD folder to the 'AutoCAD (Not Installed)' collection and wait until the deployments finish. #> function Start-PdqDeployment { [CmdletBinding()] param ( # The names of the packages you would like to deploy. [String[]]$Package, # The list of computers you would like to deploy to. [String[]]$Target, # If you use this parameter, all of the packages in the folders you specify will be deployed. [String[]]$Folder, # The collections you would like to retrieve targets from. [String[]]$Collection, # Ignore the version number in Auto Download package names. [Switch]$IgnoreVersion, # Wait for the deployments to finish before returning. [Switch]$Wait, # The number of milliseconds you would like to wait for between database queries. [Int32]$SleepMilliseconds = 1000, # The credentials you would like to use for the deployment. [String]$UserName, # The name of the Notification you would like to send when the deployment finishes. [String]$NotificationName, # Ignores your Target Filters for this deployment. [Switch]$OverrideTargetFilters, # For each target, use the credentials that are configured as the Scan User in Inventory. [Switch]$UseScanUserCredentials, # The path to the currently active database will be retrieved by default. # You can use this parameter if you wish to run this function against a different database. [String]$DatabasePath ) # The PDQ CLI EXEs must be run as an admin. $AdminState = $true try { $AdminState = [Security.Principal.WindowsPrincipal]::new([Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) } catch { throw 'Unable to determine elevation level. Please restart PowerShell as an administrator.' } if ( $AdminState -eq $false ) { throw 'This function must be run as an administrator.' } try { $CloseConnection = Open-PdqSqlConnection -Product 'Deploy' -DatabasePath $DatabasePath if ( $IgnoreVersion ) { $NewPackageNames = @() foreach ( $PackageIterator in $Package ) { $QueryParameters = @{ 'DatabasePath' = $DatabasePath 'Product' = 'Deploy' 'Query' = "SELECT Name FROM Packages WHERE Name LIKE '$PackageIterator %' AND IsAutoDownload = 1;" 'QueryType' = 'Scalar' } $PackageName = Invoke-PdqSqlQuery @QueryParameters if ( $PackageName ) { $NewPackageNames += $PackageName } else { $NewPackageNames += $PackageIterator } } $Package = $NewPackageNames } foreach ( $FolderIterator in $Folder ) { $QueryParameters = @{ 'DatabasePath' = $DatabasePath 'Product' = 'Deploy' 'Query' = "SELECT FolderId FROM Folders WHERE Path = '$FolderIterator';" 'QueryType' = 'Scalar' } $FolderId = Invoke-PdqSqlQuery @QueryParameters $QueryParameters = @{ 'DatabasePath' = $DatabasePath 'Product' = 'Deploy' 'Stream' = $true 'Query' = "SELECT Path FROM Packages WHERE FolderId = $FolderId;" } $Package += (Invoke-PdqSqlQuery @QueryParameters).Path } if ( -not $Package ) { throw 'You must provide -Package and/or -Folder.' } foreach ( $CollectionIterator in $Collection ) { $Target += PDQInventory.exe GetCollectionComputers "$CollectionIterator" } if ( -not $Target ) { throw 'You must provide -Target and/or -Collection.' } $SharedDeploymentParameters = '-Targets {0}' -f ($Target -join ' ') if ( $UserName ) { $SharedDeploymentParameters += ' -UserName "{0}"' -f $UserName } if ( $NotificationName ) { $SharedDeploymentParameters += ' -NotificationName "{0}"' -f $NotificationName } if ( $OverrideTargetFilters ) { $SharedDeploymentParameters += ' -OverrideTargetFilters' } if ( $UseScanUserCredentials ) { $SharedDeploymentParameters += ' -UseScanUserCredentials' } $DeploymentIDs = New-Object System.Collections.Generic.List[Int32] foreach ( $PackageIterator in $Package ) { $DeploymentParameters = 'PDQDeploy.exe Deploy -Package "{0}" {1} 2>&1' -f $PackageIterator, $SharedDeploymentParameters Write-Verbose $DeploymentParameters try { $DeploymentOutput = Invoke-Expression -Command $DeploymentParameters -ErrorAction 'Stop' $DeploymentId = [Int32]($DeploymentOutput[1] -split ':')[1].Trim() $DeploymentIDs.Add($DeploymentId) [PSCustomObject]@{ 'ID' = $DeploymentId 'Package' = ($DeploymentOutput[2] -split ':', 2)[1].Trim() 'TargetCount' = [Int32]($DeploymentOutput[3] -split ':')[1].Trim() } } catch { Write-Error $DeploymentOutput } } if ( $Wait ) { Wait-PdqDeployment -Id $DeploymentIDs -SleepMilliseconds $SleepMilliseconds } } finally { Close-PdqSqlConnection -Product 'Deploy' -CloseConnection $CloseConnection } } |