Download SCCM Packages

Here’s my first tool that I will share with the community : Download SCCM Packages.

With SCCM 2007, it was possible the browse for all packages available on a server using the share SMSPGKD$ (D being the share drive folder all SCCM packages (could be another drive)). In some cases, the technicians had to install a software in a hurry instead of waiting 1h to install a software with SCCM. They were used to get the installation files from the primary or secondary server on \\ServerName\SMSPKGD$\<PackageID> and proceed with installation.

Now with the new SCCM 2012 “single-instance store” library feature (explained here : http://blogs.technet.com/b/configmgrteam/archive/2013/10/29/understanding-the-configuration-manager-content-library.aspx), it’s not possible anymore. So I’ve been challenged to find an alternative.

The service used to download Packages, Applications and Updates is Internet Information Services (IIS) and you can see the download location in the C:\Windows\CCM\Logs\ContentTransferManager.log (something like this :  Persisted locations for CTM job {A013F28D-DA1D-4B55-8BC7-63BC3C8722E5}:(LOCAL) http://ServerName/SMS_DP_SMSPKG$/MTL00123 ). Easy! Now let’s create the tool the download each links on this webpage.

Using Powershell Studio 2012, I created a GUI that looks like this :

DownloadSCCMPackages

Once you got the SCCM Server (or DP) and the Package/Application ID, you are now ready to download the files :

DownloadStuff $SCCMWebLink $destinationFolder

using this function :


function DownloadStuff($link, $destinationFolder){
$HTTPSubfolders = @()
$wc = New-Object System.Net.WebClient
$wc.UseDefaultCredentials = $true
try{$Webpage = Invoke-WebRequest -Uri $link -UseDefaultCredentials -UseBasicParsing}
catch{$ErrorMessage = $_.Exception.Message}
$WebpageContent = $Webpage.content -split "<br>"

$WebpageContent | foreach{
if ($_ -like "*dir&*"){
$a = $_.IndexOf("/")
$b = $_.IndexOf('">http')
$folderName = $_.substring($a,$b-$a)
while ($folderName -like "*/*"){
$c = $folderName.IndexOf("/")
if ($c -eq 0){$c = $c+1 }
$d = $folderName.length
$folderName = $folderName.substring($c,$d-$c)
}
$HTTPSubfolders += "$link/$folderName"
}
elseif ($_ -like "*href*"){
$e = $_.IndexOf('http://')
$f = $_.IndexOf('">http')
$downloadablelink = $_.substring($e,$f-$e)
$Filename = [System.IO.Path]::GetFileName($downloadablelink)
mkdir $destinationFolder -force
$destinationFolder1 = "$([char]34)$destinationFolder\$([char]34)"

$Filename = $Filename -replace('%20',' ')
$destinationFolder1 = "$destinationFolder\$Filename"
Write-host "Copy in progress : $Filename"
$wc.DownloadFile($downloadablelink, $destinationFolder1)
}
}

if ($HTTPSubfolders -ne $null){
foreach($subfolder in $HTTPSubfolders){
$subinprogress = "yes"
$packageWebLink = $link -replace ("\$", "")
$subfoldertocreate = $subfolder -replace ("\$", "")
$subfoldertocreate = $subfoldertocreate -replace ($packageWebLink,"")
$subfoldertocreate = $subfoldertocreate -replace ("/","\")
$NewDestinationFolder = "$destinationFolder$subfoldertocreate"

mkdir $NewDestinationFolder -force
DownloadStuff "$subfolder" $NewDestinationFolder
}
}
Write-host "Operation completed : $SelectedPackage"
}

Happy scripting and have fun!

Leave a Reply