Public/Get-PdqDeployment.ps1

<#
.SYNOPSIS
Retrieves information about deployments from the Deploy database.
 
.INPUTS
None.
 
.OUTPUTS
System.Management.Automation.PSCustomObject
System.Object[]
 
.EXAMPLE
Get-PdqDeployment | Where-Object 'Status' -eq 'Running' | Select-Object 'DeploymentId', 'PackageName'
Returns the Deployment ID and Package Name for all running deployments.
 
.EXAMPLE
(Get-PdqDeployment -Id 12 -IncludeComputers).Computers.Name
Returns the names of the computers in Deployment 12.
#>


function Get-PdqDeployment {

    [CmdletBinding()]
    param (
        # The IDs of the deployments you would like to retrieve.
        [UInt32[]]$Id,

        # Add the Computers property.
        # The objects in this array come from the DeploymentComputers table.
        [Switch]$IncludeComputers,

        # Add the Steps property to each object in the Computers property.
        # The objects in this array come from the DeploymentComputerSteps table.
        [Switch]$IncludeSteps,

        # 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
    )

    try {

        $CloseConnection = Open-PdqSqlConnection -Product 'Deploy' -DatabasePath $DatabasePath

        $FoundDeploymentIds = New-Object System.Collections.Generic.List[UInt32]

        # Get all deployments.
        Invoke-SqlQuery -Query 'SELECT * FROM Deployments;' -ConnectionName 'Deploy' -Stream | ForEach-Object {

            $Deployment = $_

            # Skip deployments if their DeploymentId isn't in $Id.
            if ( (-not $Id) -or ($Deployment.DeploymentId -in $Id) ) {

                $FoundDeploymentIds.Add($Deployment.DeploymentId)

                if ( $IncludeComputers ) {

                    $Computers = New-Object System.Collections.Generic.List[Object]

                    # Get all computers in the deployment.
                    $ComputersQuery = "SELECT * FROM DeploymentComputers WHERE DeploymentId = $($Deployment.DeploymentId);"
                    Invoke-SqlQuery -Query $ComputersQuery -ConnectionName 'Deploy' -Stream | ForEach-Object {

                        $Computer = $_

                        if ( $IncludeSteps ) {

                            # Get every step of this computer's deployment.
                            $StepsQuery = "SELECT * FROM DeploymentComputerSteps WHERE DeploymentComputerId = $($Computer.DeploymentComputerId);"
                            $Steps = Invoke-SqlQuery -Query $StepsQuery -ConnectionName 'Deploy' -Stream

                            # Add the steps to the $Computer object.
                            $Computer | Add-Member -MemberType 'NoteProperty' -Name 'Steps' -Value $Steps

                        }

                        # Add this computer to the list of computers, so they can be added to the deployment.
                        $Computers.Add($Computer)

                    }

                    # Add the computers to the $Deployment object.
                    # .ToArray() converts the List into a standard System.Object[].
                    # I did this so the data type matches $Steps. It's probably unnecessary, but might prevent unexpected behavior.
                    $Deployment | Add-Member -MemberType 'NoteProperty' -Name 'Computers' -Value $Computers.ToArray() -PassThru

                } else {

                    $Deployment

                }

            }

        }

        foreach ( $DesiredId in $Id ) {

            if ( $DesiredId -notin $FoundDeploymentIds ) {

                throw "DeploymentId $DesiredId does not exist in this database."

            }

        }

    } finally {

        Close-PdqSqlConnection -Product 'Deploy' -CloseConnection $CloseConnection

    }

}