Monday, January 21, 2019

SCCM Powershell script to add package to Distribution Point - SCCM_AddPackageToDP.ps1

 Below a script permitting to add Package to Distribution Point/Pull DP
Option -ForceToDeletePackageBeforeIfExist delete 1st and add when there is a problem

Example :
.\SCCM_AddPackageToDP.ps1 -DistPoint "SERVER01" -Package "ABC00123"


Example if you want to use a .csv file like this below

"PackageID";"DistributionPoint";"SiteCode"
"XXX00233";"computerdp1";"ABC"
"XXX00233";"computerdp2";"ABC"


 .\SCCM_AddPackageToDP.ps1 -ImportFilePath .\mydp.csv  





<#
.Synopsis
   Add Package to Distribution Point
.EXAMPLE
   SCCM_AddPackageToDP.ps1 -DistPoint "SERVER01" -Package "ABC00123"
#>
[cmdletbinding()]
Param(
    [String]$ImportFilePath=""
    ,[String]$DistPoint=""
    ,[String]$Package=""
    ,[String]$CM="mycm.mydomain.net"
    ,[String]$PrimarySiteCode="XXX"
    ,[switch]$ForceToDeletePackageBeforeIfExist
)

# For Time checking
$MeasureCommandBegin = Get-Date           


$strCurDir = Split-Path -parent $MyInvocation.MyCommand.Path
$strScriptName = $MyInvocation.MyCommand.Name
$date_for_file = Get-Date -format "yyyy-MM-dd_HHmmss"


#Import the Module
Import-Module $env:SMS_ADMIN_UI_PATH.Replace("\bin\i386","\bin\configurationmanager.psd1")





# to do BEFORE cd ABC: sitecode
#
[ARRAY]$arrItems = @()
if ($ImportFilePath -ne "") {
    If ( (Test-Path -Path "$ImportFilePath") -eq $False ) {
        Write-host -ForegroundColor Red "file '$($ImportFilePath)' NOT exist. Please indicate real file path."
        cd $strCurDir
        Exit
    }

    Write-Host "Get '$($ImportFilePath)' content"
    $arrItems = Import-Csv $ImportFilePath -Delimiter ';'        #Import CSV into array
    Write-Host "Number of line: $($arrItems.Count)"
    if ($arrItems.Count -eq 0) {
        Write-host "file '$($ImportFilePath)' NO line. Please check It. Must have this header:" -ForegroundColor Red
        Write-host "DistributionPoint;PackageId"  -ForegroundColor Red
        cd $strCurDir
        Exit
    }
}



$Error.Clear()
if ($PrimarySiteCode) {
    Set-Location "$($PrimarySiteCode):\"
} else {
    $CMSITE = Get-PSDrive -PSProvider CMSITE    # multiple not work
    if ($CMSITE.GetType().Name -eq "Object[]") {
        $sitecodes = ""
        $CMSITE | ForEach-Object { $sitecodes = $_.Name + " " + $sitecodes }
        Write-Host "Please indicate Which Site Code to use in parameter 'PrimarySiteCode'. Choose using one of them: $sitecodes"

        Exit
    } else {
        Set-Location "$($CMSITE.Name):\"
    }
}
if ($Error) {
    $Error
    Write-Host "if not found can be necessary to do a 'Remove-Module ConfigurationManager' "
    cd $strCurDir
    Exit
}







if ($ImportFilePath -eq "") {
    if ($DistPoint -eq "" -or $Package -eq "") {
        Write-Host "You need at least Parameter 1 -DistPoint for 'Distribution Point' and -Package for package(s)"
        Write-Host "either -DistPoint for 'Distribution Point' and -Package for package(s)"
        Write-Host "either -ImportFilePath for path with all DistributionPoint;PackageId lines"
        cd $strCurDir
        Exit
    }

    $Query = "Select NALPath,Name From SMS_DistributionPointInfo Where ServerName Like '%$DistPoint%'"
    [Array] $arrDistributionPoint = @()
    $arrDistributionPoint = @(Get-WmiObject -Namespace "root\SMS\Site_$PrimarySiteCode" -Query $Query -ComputerName $CM)
    if($arrDistributionPoint.Count -ne 1) {       
        Foreach($DP in $arrDistributionPoint) {
            Write-host $DP.Name -ForegroundColor Yellow
        }
        Write-host "Found $($arrDistributionPoint.Count) matching Distribution Points. Please redefine query." -ForegroundColor Red
        cd $strCurDir
        Exit
    }
    else
    {
        $ServerNalPath = $arrDistributionPoint.NALPath -replace "([\[])",'[$1]' -replace "(\\)",'\$1'
        $DPname = $arrDistributionPoint.Name
        Write-Host "Distribution Point: $ServerNalPath"
    }
    Foreach ($pkg in $Package) {
        $item = New-Object –TypeNamePSObject
        $item | Add-Member –MemberTypeNoteProperty –Name DistributionPoint –Value $DPname
        $item | Add-Member –MemberTypeNoteProperty –Name PackageId –Value $pkg
        $arrItems += $item
    }


}

# Get all packages
#
Write-Host "Get all Packages"
[HashTable] $hashPackageType = @{}
$arrSMS_PackageBaseclass = @(Get-WmiObject -Namespace "root\SMS\Site_$PrimarySiteCode" -Class SMS_PackageBaseclass -ComputerName $CM)
Foreach ($SMS_PackageBaseclass in $arrSMS_PackageBaseclass) { 
    if ($hashPackageType.ContainsKey($SMS_PackageBaseclass.PackageID) ) {
        # Should not arrive problem in DB
    } else {
        $hashPackageType[$($SMS_PackageBaseclass.PackageID)] = $($SMS_PackageBaseclass.PackageType)
    }
}

[ARRAY] $arrCmdRemoveContent = @()
[ARRAY] $arrCmdAddContent = @()
[HashTable] $hashDPExist = @{}
[HashTable] $hashDPExistingPackages = @{}
$NbItemStay = $($arrItems.Count)
Foreach ($item in $arrItems) {

    Write-host "-----------------------"
    Write-host "Nb of items remaining: $($NbItemStay)"
    $NbItemStay = $NbItemStay -1
    $bError = $false


    $DistributionPoint = $item.DistributionPoint
    if ($DistributionPoint.length -eq 0) {
        Write-host "Value SiteServer $($DistributionPoint) NOT exist" -ForegroundColor Red
        $bError = $True
    } else {
        if ( $hashDPExist.ContainsKey($DistributionPoint) ){
            # OK already do some actions to verify it exist
        } else {

<#
            # DNS test
            Try {   
                $result = Resolve-DNSName -Name $DistributionPoint -Type A -ErrorAction Stop
                Write-host "SiteServer $($DistributionPoint) DNS OK"
                $hashDPExist[$DistributionPoint]= 1
            } Catch {
                Write-host "Cannot Resolve DNS for $($DistributionPoint) " -ForegroundColor Red
                $bError = $True
            }
#>

            $Query = "Select NALPath,Name From SMS_DistributionPointInfo Where ServerName Like '%$DistributionPoint%'"
            [Array]$arrDistributionPoint = @()
            $arrDistributionPoint = @(Get-WmiObject -Namespace "root\SMS\Site_$PrimarySiteCode" -Query $Query -ComputerName $CM)
            if($arrDistributionPoint.Count -ne 1) {       
                Foreach($DP in $arrDistributionPoint) {
                    Write-host $DP.Name -ForegroundColor Yellow
                }
                Write-host "Found $($arrDistributionPoint.Count) matching Distribution Points. Please redefine query." -ForegroundColor Red
                $bError = $True
            }
            else
            {
                $ServerNalPath = $arrDistributionPoint.NALPath -replace "([\[])",'[$1]' -replace "(\\)",'\$1'
                $DPname = $arrDistributionPoint.Name
                Write-Host "Distribution Point: $ServerNalPath"

                $hashDPExist[$DistributionPoint] = $DPname


                $Query = "Select PackageID From SMS_PackageStatusDistPointsSummarizer Where ServerNALPath Like '$ServerNALPath'"
                [ARRAY]$arrPackages = @()    # to be sure to count to be an array (else string not count work)
                $arrPackages = Get-WmiObject -Namespace "root\SMS\Site_$PrimarySiteCode" -Query $Query -ComputerName $CM
                Foreach ($pkg in $arrPackages) {
                    $hashline = $DPname + "_" + $pkg.PackageID
                    $hashDPExistingPackages[$hashline] = 1
                }

            }


        }
    }

    $PackageID = $item.PackageID
    if ($PackageID.length -eq 0) {
        Write-host "Value SiteServer $($DistributionPoint) NOT exist" -ForegroundColor Red
        $bError = $True
    } else {
        if ( ($PackageID.Substring(3,5) -eq "00003") -or ($PackageID.Substring(3,5) -eq "00008") ) {
            Write-host "Package $PackageID cannot be redistribute - it is hidden package"
            continue
        }
        if ( $hashPackageType.ContainsKey($PackageID) ) {
            # OK already do some actions to verify it exist
        } else {
            Write-host -ForegroundColor Red "Package $($PackageID) NOT exist"
            $bError = $True
        }
    }

    if ($bError) {
        Write-host "Error line $($item) - NOT DONE -" -ForegroundColor Red
        continue
    }




    $DPname = $hashDPExist[$DistributionPoint]
    $DPType = $hashPackageType[$PackageID]

    Write-Host  $DistributionPoint - $DPname - $PackageID - $DPType
    if (!$DPname -or !$PackageID) {
        Write-Host  "Error: DistributionPoint:$($DistributionPoint) - DPname:$($DPname) - PackageID:$($PackageID) - DPType:$($DPType)"
        continue
    }   

    $hashline = $DPname + "_" + $PackageID
    if ( ($hashDPExistingPackages.ContainsKey($hashline)) -and (!$ForceToDeletePackageBeforeIfExist) ) {
        #
        Write-Host " DP '$DPname' has already $PackageID - NOT Distribute it again - Use -Force to remove and add it"
        continue
    } else {
        $hashDPExistingPackages[$hashline] = 1

        $ContDistCmdParam = ""
            Switch ($DPType) {
            0 {
                $DPTypeValue = "Standard Package"
                $ContDistCmdParam = "-PackageID"
            }
            3 {
                $DPTypeValue = "Driver Package"
                $ContDistCmdParam = "-DriverPackageId"
            }
            4 {
                $DPTypeValue = "Task Sequence Package"
                $ContDistCmdParam = "-TaskSequenceId"
            }
            5 {
                $DPTypeValue = "Software Update Package"
                $ContDistCmdParam = "-DeploymentPackageId"
            }
            6 {
                $DPTypeValue = "Device Setting Package"
            }
            7 {
                $DPTypeValue = "Virtual App Package"
            }
            8 {
                $DPTypeValue = "Application Package"
                $ContDistCmdParam = "-ApplicationId"
            }
            257 {
                $DPTypeValue = "Operating system Image Package"
                $ContDistCmdParam = "-OperatingSystemImageId"
            }
            258 {
                $DPTypeValue = "Boot Image Package"
                $ContDistCmdParam = "-BootImageId"
            }
            259 {
                $DPTypeValue = "Operating System Upgrade Package"
                $ContDistCmdParam = "-OperatingSystemInstallerId"
            }
            260 {
                $DPTypeValue = "VHD package"
                Write-Host "Distribute '$DPTypeValue' to DP '$DPname'"
            }
        } # switch end


        if ($ContDistCmdParam) {
            if ($ForceToDeletePackageBeforeIfExist) {
                Write-Host "Force: Remove $PackageID '$DPTypeValue' from DP '$DPname'"
                $cmd = "Remove-CMContentDistribution $ContDistCmdParam $PackageID -DistributionPointName $DPname -Force"
                $arrCmdRemoveContent += $cmd
                #Invoke-Expression $cmd
                #Write-Host "Wait 15 sec"
                #Start-Sleep -s 15
            }

            Write-Host "Distribute $PackageID '$DPTypeValue' to DP '$DPname'"
            $cmd = "Start-CMContentDistribution $ContDistCmdParam $PackageID -DistributionPointName $DPname"
            $arrCmdAddContent += $cmd
            #Invoke-Expression $cmd

        } else {
            Write-Host "NOT Distribute $PackageID '$DPTypeValue' to DP '$DPname'"
        }

    }
}

Foreach ($cmd in $arrCmdRemoveContent) {
    Write-Host $cmd
    Invoke-Expression $cmd
}

Write-Host "Wait 15 sec"
Start-Sleep -s 15

Foreach ($cmd in $arrCmdAddContent) {
    Write-Host $cmd
    Invoke-Expression $cmd
}


cd $strCurDir



$MeasureCommandEnd = Get-Date
$MeasureCommandTime = $MeasureCommandEnd - $MeasureCommandBegin
Write-host "Script Executing in $($MeasureCommandTime.Day) day(s) $($MeasureCommandTime.Hour) hour(s) $($MeasureCommandTime.Minutes) minute(s) $($MeasureCommandTime.Seconds) second(s) "



No comments: