Wednesday, January 29, 2014

Powershell script to find in which deployment package a software update is

Troubleshooting security updates stuck at “downloading 0%”  in Software Center, I’m often wondering in which “Deployment Packages” xxxxxxxx update is located ? 
I spent some times opening each deployment packages and see if the update is there… That bored me and decided to write a powershell script…
Replace ServerName and SiteCode by yours.


$ServerName = "Server FQDN"
$SiteCode = "XXX"
$ArticleID = Read-Host "Enter Article ID"

$AllPkgUpdate = Get-WmiObject –NameSpace Root\SMS\Site_$SiteCode –Class SMS_SoftwareUpdatesPackage -ComputerName $ServerName | Select PackageID,Name
$update = Get-WmiObject –NameSpace Root\SMS\Site_$SiteCode –Class SMS_SoftwareUpdate -ComputerName $ServerName –Filter ArticleID="'$ArticleID'" | Select CI_UniqueID,LocalizedDisplayName,CI_ID

Foreach ($objectUpdate in $update)
{
$Question = Read-Host "Do you want to look for " $objectUpdate.LocalizedDisplayName " ? (Y/N)"
    If ($Question -eq "Y")
    {
    $UniqueID = $objectUpdate.CI_UniqueID
    $ContentID= Get-WmiObject –NameSpace Root\SMS\Site_$SiteCode –Class SMS_CIToContent -ComputerName $ServerName –Filter CI_UniqueID="'$UniqueID'" | Select ContentID
    $TargetUpdate = $ContentID | ForEach-Object {$_.ContentID}
    Write-Host "Please wait..."
        Foreach ($PkgItem in $AllPkgUpdate)
        {
        $PkgID = $PkgItem.PackageID
        $ArrContentID = Get-WmiObject –NameSpace Root\SMS\Site_$SiteCode –Class SMS_PackageToContent -ComputerName $ServerName –Filter PackageID="'$PkgID'" | Select ContentID
        $TargetContentID = $ArrContentID | ForEach-Object {$_.ContentID}
            If ($TargetUpdate -isnot [system.array])
            {$Test = $TargetContentID -contains $TargetUpdate}
            Else{$Test = -not ($TargetUpdate | where {$TargetContentID -notcontains $_}).count}
            If ($Test -eq $true)
            {$PkgName = $PkgItem.Name
            Write-Host $objectUpdate.LocalizedDisplayName " found in "$PkgName" - "$PkgID
            }
        }
    }

}

Wednesday, September 18, 2013

Powershell Script to check a package distribution status

Here is a Powershell script to check a package distribution status.
Next step would be to send an email when status get Completed or Failed. To do so i would have liked to use Wmi-Event... but so far i wasn't able to implement it... don't hesitate to contact me if you think you can help me !

Replace ServerName and SiteCode by yours.

$ServerName = "ServerFQDN"
$SiteCode = "XXX"
$PkgID = Read-Host "Enter PackageID"

$query = Get-WmiObject –NameSpace Root\SMS\Site_$SiteCode –Class SMS_DistributionDPStatus -ComputerName $ServerName –Filter "PackageID='$PkgID'" | Select Name, MessageID, MessageState, LastUpdateDate

If ($query -eq $null)
{Write-Host "PackageID not found"
Exit
}

Foreach ($objItem in $query)

{
$DPName = $objItem.Name
$UpdDate = [System.Management.ManagementDateTimeconverter]::ToDateTime($objItem.LastUpdateDate)

switch ($objItem.MessageState)
  {
  1 {$Status = "Success"}
  2 {$Status = "In Progress"}
  3 {$Status = "Failed"}
  }

switch ($objItem.MessageID)
    {
    2303      {$Message = "Content was successfully refreshed"}
    2323      {$Message = "Failed to initialize NAL"}
    2324      {$Message = "Failed to access or create the content share"}
    2330      {$Message = "Content was distributed to distribution point"}
    2354      {$Message = "Failed to validate content status file"}
    2357      {$Message = "Content transfer manager was instructed to send content to Distribution Point"}
    2360      {$Message = "Status message 2360 unknown"}
    2370      {$Message = "Failed to install distribution point"}
    2371      {$Message = "Waiting for prestaged content"}
    2372      {$Message = "Waiting for content"}
    2380      {$Message = "Content evaluation has started"}
    2381      {$Message = "An evaluation task is running. Content was added to Queue"}
    2382      {$Message = "Content hash is invalid"}
    2383      {$Message = "Failed to validate content hash"}
    2384      {$Message = "Content hash has been successfully verified"}
    2391      {$Message = "Failed to connect to remote distribution point"}
    2398      {$Message = "Content Status not found"}
    8203      {$Message = "Failed to update package"}
    8204      {$Message = "Content is being distributed to the distribution Point"}
    8211      {$Message = "Failed to update package"}
    }
Write-Host "Package $PkgID on $DPName is in '$Status' state"
Write-Host "Detail: $Message"
Write-Host "Last Update Date: $UpdDate"


Friday, September 6, 2013

Powershell Script to delete all elements in Configuration Manager client cache

You may need to delete all elements in Configuration Manager client cache. Here it is in a Powershell way:

#Delete all elements in Configuration Manager client cache

$CMObject = New-Object -ComObject "UIResource.UIResourceMgr"
$CMCacheObjects = $CMObject.GetCacheInfo()
$CMCacheElements = $CMCacheObjects.GetCacheElements()

Foreach ($CacheElement in $CMCacheElements) 
    {
    $CMCacheObjects.DeleteCacheElementEx($CacheElement.CacheElementID)
    } 

Thursday, July 11, 2013

Powershell script to enable command-shell in winPE 3.1 boot images for use in ConfigMgr 2012 R2

Following Brandon Linton's post about creating and importing a WinPE 3.1 boot image for use in ConfigMgr 2012 SP1 CU2, below is a little Powershell script to enable command-shell


#CM2012 R2 - Enable Command-Shell in WinPE 3.1 Boot Image

#Replace below OSDxxxxx with your boot image package ID
$BootImagePackageID = "OSDxxxxx" 

#Get the Boot image - Replace OSD by your site code
$BootImageQuery = Get-WmiObject -Namespace "Root\SMS\Site_OSD" -Class SMS_BootImagePackage -Filter "PackageID='$BootImagePackageID'"

#Read Properties
$BootImageQuery.Get()

#Enable Command-Shell
$BootImageQuery.EnableLabShell = 'True'
$BootImageQuery.Put()

#Update Distribution Points
$BootImageQuery.RefreshPkgSource()