Public/Start-DPGroupContentDistribution.ps1
function Start-DPGroupContentDistribution { <# .SYNOPSIS Distributes objects to a given distribution point group. The function can accept input object from Get-DPContent, by manually specifying -ObjectID and -ObjectType or by using -Folder where it will distribute all objects for .pkgx files found in said folder. .PARAMETER InputObject A PSObject type "PSCMContentMgmt" generated by Get-DPContent .PARAMETER DistributionPointGroup Name of distribution point group you want to distribute objects to. .PARAMETER ObjectID Unique ID of the content object you want to distribute. For Applications the ID must be the CI_ID value whereas for all other content objects the ID is PackageID. When using this parameter you must also use ObjectType. .PARAMETER ObjectType Object type of the content object you want to distribute. Can be one of the following values: "Package", "DriverPackage", "DeploymentPackage", "OperatingSystemImage", "OperatingSystemInstaller", "BootImage", "Application". When using this parameter you must also use ObjectID. .PARAMETER Folder For all .pkgx files in this folder that use the following naming convention "<ObjectType>_<ObjectID>.pkgx", distribute the <ObjectID> of type <ObjectType> to -DistributionPoint. This can be useful if you have a folder filled with .pkgx files, generated by Export-DPContent, and want to distribute those objects to a distribution point. .PARAMETER SiteServer It is not usually necessary to specify this parameter as importing the PSCMContentMgr module sets the $CMSiteServer variable which is the default value for this parameter. Specify this to query an alternative server, or if the module import process was unable to auto-detect and set $CMSiteServer. .PARAMETER SiteCode Site code of which the server specified by -SiteServer belongs to. It is not usually necessary to specify this parameter as importing the PSCMContentMgr module sets the $CMSiteCode variable which is the default value for this parameter. Specify this to query an alternative site, or if the module import process was unable to auto-detect and set $CMSiteCode. .EXAMPLE PS C:\> Compare-DPGroupContent -Source "London DPs" -Target "Mancester DPs" | Start-DPGroupContentDistribution -DistributionPointGroup "Mancester DPs" -WhatIf Compares the missing content objects in group Manchester DPs compared to "London DPs", and distributes them to distribution point group Manchester DPs. .EXAMPLE PS C:\> Start-DPGroupContentDistribution -Folder "E:\exported" -DistributionPointGroup "London DPs" -WhatIf For all .pkgx files in folder "E:\exported" that use the following naming convention "<ObjectType>_<ObjectID>.pkgx", distributes them to distribution point group "London DPs". .EXAMPLE PS C:\> Start-DPGroupContentDistribution -ObjectID ACC00007 -ObjectType Package -DistributionPointGroup "London DPs" -WhatIf Nothing more than a wrapper for Start-CMContentDistribution. Distributes package ACC00007 to distribution point group "London DPs". #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = "Medium")] param ( [Parameter(Mandatory, ValueFromPipeline, ParameterSetName="InputObject")] [PSTypeName('PSCMContentMgmt')] [PSCustomObject]$InputObject, [Parameter(Mandatory, ParameterSetName="Properties")] [ValidateNotNullOrEmpty()] [String]$ObjectID, [Parameter(Mandatory, ParameterSetName="Properties")] [ValidateSet("Package","DriverPackage","DeploymentPackage","OperatingSystemImage","OperatingSystemInstaller","BootImage","Application")] [SMS_DPContentInfo]$ObjectType, [Parameter(Mandatory, ParameterSetName="Folder")] [ValidateScript({ if (!([System.IO.Directory]::Exists($_))) { throw "Invalid path or access denied" } elseif (!($_ | Test-Path -PathType Container)) { throw "Value must be a directory, not a file" } else { return $true } })] [String]$Folder, [Parameter(ParameterSetName="InputObject")] [Parameter(Mandatory, ParameterSetName="Properties")] [Parameter(Mandatory, ParameterSetName="Folder")] [ValidateNotNullOrEmpty()] [String]$DistributionPointGroup, [Parameter()] [ValidateNotNullOrEmpty()] [String]$SiteServer = $CMSiteServer, [Parameter()] [ValidateNotNullOrEmpty()] [String]$SiteCode = $CMSiteCode ) begin { switch ($null) { $SiteCode { Write-Error -Message "Please supply a site code using the -SiteCode parameter" -Category "InvalidArgument" -ErrorAction "Stop" } $SiteServer { Write-Error -Message "Please supply a site server FQDN address using the -SiteServer parameter" -Category "InvalidArgument" -ErrorAction "Stop" } } $TargetDPGroup = $DistributionPointGroup if ($PSCmdlet.ParameterSetName -ne "InputObject") { $InputObject = [PSCustomObject]@{ ObjectID = $ObjectID ObjectType = $ObjectType DistributionPointGroup = $TargetDPGroup } } if ($PSCmdlet.ParameterSetName -eq "Folder") { $Files = Get-ChildItem -Path $Folder -Filter "*.pkgx" try { Resolve-DPGroup -Name $TargetDPGroup -SiteServer $SiteServer -SiteCode $SiteCode } catch { $PSCmdlet.ThrowTerminatingError($_) } } $OriginalLocation = (Get-Location).Path if ($null -eq (Get-PSDrive -Name $SiteCode -PSProvider "CMSite" -ErrorAction "SilentlyContinue")) { $null = New-PSDrive -Name $SiteCode -PSProvider "CMSite" -Root $SiteServer -ErrorAction "Stop" } Set-Location ("{0}:\" -f $SiteCode) -ErrorAction "Stop" } process { try { switch ($PSCmdlet.ParameterSetName) { "Folder" { foreach ($File in $Files) { if ($File.Name -match "^(?<ObjectType>0|3|5|257|258|259|512)_(?<ObjectID>[A-Za-z0-9]+)\.pkgx$") { $InputObject = [PSCustomObject]@{ ObjectID = $Matches.ObjectID ObjectType = $Matches.ObjectType } $result = @{ PSTypeName = "PSCMContentMgmtDistribute" ObjectID = $InputObject.ObjectID ObjectType = [SMS_DPContentInfo]$InputObject.ObjectType Message = $null } $Command = 'Start-CMContentDistribution -{0} "{1}" -DistributionPointGroupName "{2}" -ErrorAction "Stop"' -f [SMS_DPContentInfo_CMParameters][SMS_DPContentInfo]$InputObject.ObjectType, $InputObject.ObjectID, $TargetDPGroup $ScriptBlock = [ScriptBlock]::Create($Command) try { if ($PSCmdlet.ShouldProcess( ("Would distribute '{0}' ({1}) to '{2}'" -f $InputObject.ObjectID, [SMS_DPContentInfo]$InputObject.ObjectType, $TargetDPGroup), "Are you sure you want to continue?", ("Distributing '{0}' ({1}) to '{2}'" -f $InputObject.ObjectID, [SMS_DPContentInfo]$InputObject.ObjectType, $TargetDPGroup))) { Invoke-Command -ScriptBlock $ScriptBlock -ErrorAction "Stop" $result["Result"] = "Success" } else { $result["Result"] = "No change" } } catch { Write-Error -ErrorRecord $_ $result["Result"] = "Failed" $result["Message"] = $_.Exception.Message } if (-not $WhatIfPreference) { [PSCustomObject]$result } } else { Write-Warning ("Skipping '{0}'" -f $File.Name) } } } default { foreach ($Object in $InputObject) { switch ($true) { ($LastDPGroup -ne $Object.DistributionPointGroup -And -not $PSBoundParameters.ContainsKey("DistributionPointGroup")) { $TargetDPGroup = $Object.DistributionPointGroup } ($LastDPGroup -ne $TargetDPGroup) { try { Resolve-DPGroup -Name $TargetDPGroup -SiteServer $SiteServer -SiteCode $SiteCode } catch { Write-Error -ErrorRecord $_ return } $LastDPGroup = $TargetDPGroup } default { $LastDPGroup = $TargetDPGroup } } $result = @{ PSTypeName = "PSCMContentMgmtDistribute" ObjectID = $Object.ObjectID ObjectType = $Object.ObjectType Message = $null } $Command = 'Start-CMContentDistribution -{0} "{1}" -DistributionPointGroupName "{2}" -ErrorAction "Stop"' -f [SMS_DPContentInfo_CMParameters][SMS_DPContentInfo]$Object.ObjectType, $Object.ObjectID, $TargetDPGroup $ScriptBlock = [ScriptBlock]::Create($Command) try { if ($PSCmdlet.ShouldProcess( ("Would distribute '{0}' ({1}) to '{2}'" -f $Object.ObjectID, $Object.ObjectType, $TargetDPGroup), "Are you sure you want to continue?", ("Distributing '{0}' ({1}) to '{2}'" -f $Object.ObjectID, $Object.ObjectType, $TargetDPGroup))) { Invoke-Command -ScriptBlock $ScriptBlock -ErrorAction "Stop" $result["Result"] = "Success" } else { $result["Result"] = "No change" } } catch { Write-Error -ErrorRecord $_ $result["Result"] = "Failed" $result["Message"] = $_.Exception.Message } if (-not $WhatIfPreference) { [PSCustomObject]$result } } } } } catch { Set-Location $OriginalLocation $PSCmdlet.ThrowTerminatingError($_) } } end { Set-Location $OriginalLocation } } |