Forzar al punto de distribución SCCM a actualizar los paquetes fallidos
Si un punto de distribución en System Center Configuration Manager tiene paquetes fallidos, probablemente tenga una causa y reenviar los paquetes podría no ser la solución adecuada al problema.
Pero tenía la necesidad de reenviar todos los paquetes fallidos en un punto de distribución y no estaba de humor para hacer clic en la GUI, así que investigué las clases WMI enumeradas en MSDN: http://msdn.microsoft.com/en-us/ biblioteca/hh949540.aspx
En primer lugar, lo que busco son paquetes en un determinado punto de distribución. Estos se enumeran en la clase SMS_PackageStatusDistPointsSummarizer documentada aquí: http://msdn.microsoft.com/en-us/library/hh949126.aspx
La clase tiene una Propiedad llamada Estado con los siguientes estados disponibles:
0 INSTALLED
1 INSTALL_PENDING
2 INSTALL_RETRYING
3 INSTALL_FAILED
4 REMOVAL_PENDING
5 REMOVAL_RETRYING
6 REMOVAL_FAILED
Para empezar, filtré los paquetes después de que el estado fuera 2 o 3, pero no hay ninguna propiedad obvia que contenga el nombre del punto de distribución, solo la propiedad ServerNALPath.
Después de investigar un poco más en MSDN, encontré la clase WMI SMS_DistributionPointInfo que se puede usar para recuperar el Nombre y ServerNALPath para un punto de distribución. ¡GANAR!
Entonces, para empezar, obtenga la información del punto de distribución:
$Query = "Select NALPath,Name From SMS_DistributionPointInfo Where ServerName Like '%$DistPoint%'"
$DistributionPoint = @(Get-WmiObject -Namespace "rootSMSSite_$SiteCode" -Query $Query)
$ServerNalPath = $DistributionPoint.NALPathEn la primera fila utilizo el operador "Me gusta" que en WQL admite comodines mediante el uso de "%" y una sintaxis similar a una expresión regular (más sobre esto más adelante).
En la segunda fila utilizo un truco para devolver el resultado en una matriz, de eso se trata @(). De esta manera obtengo la propiedad Count on $DistributionPoint incluso si la consulta solo devuelve un elemento.
Luego necesito encontrar todos los paquetes fallidos o reintentados en ese DistributionPoint. Primero probé algo como esto:
$Query = "Select PackageID From SMS_PackageStatusDistPointsSummarizer Where ServerNALPath Like '$ServerNALPath' AND (State = 2 OR state = 3)"
$FailedPackages = Get-WmiObject -Namespace "rootSMSSite_$SiteCode" -Query $QueryPero espera, eso me da un error que dice:
Get-WmiObject : Invalid query “Select PackageID From SMS_PackageStatusDistPointsSummarizer Where ServerNALPath Like ‘[“Display=\SERVER01.
lab.lcl”]MSWNET:[“SMS_SITE=S01″]\SERVER01.lab.lcl’ AND (State = 2 OR state = 3)”
At line:1 char:23
+ $FailedPackages = Get-WmiObject -Namespace “rootSMSSite_$SiteCode” -Query …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommandEl problema es que ServerNALPath contiene corchetes "[]", lo que le dice a WQL que busque uno de los caracteres entre corchetes y no encontrará lo que quiero. La solución a esto es rodear el carácter [-con corchetes como este: “[[]” indicando a WQL que busque cualquiera de los caracteres “[“, que es solo un carácter. Dado que WQL no interpretará el corchete de apertura, el corchete de cierre "]" también se ignorará. El siguiente problema es que la barra invertida “ ” es un carácter de escape que le dice a WQL que el siguiente carácter debe interpretarse literalmente y no como un carácter especial, lo que significa que\se traducirá solo a . Para solucionar esto también tendremos que escapar de cada uno con un .
Ambas operaciones se realizan fácilmente en PowerShell utilizando el operador de reemplazo en $ServerNalPath:
$ServerNalPath=$DistributionPoint.NALPath -reemplazar “([[]) ”,’[$1]’ -reemplazar “() ”,’$1′
Esto hará que mi $ServerNalPath se vea así:
[[]”Display=\SERVER01.lab.lcl”]MSWNET:[[]”SMS_SITE=S01″]\SERVER01.lab.lcl
Esto parece un poco extraño, pero hará que mi consulta se ejecute sin errores. Ahora solo tengo que recorrer cada uno de los paquetes fallidos y establecer la propiedad "RefreshNow" en True y llamar al método Put para aplicar mi nueva configuración:
Foreach($Package in $FailedPackages)
{
$Query = "Select * From SMS_DistributionPoint WHERE SiteCode='$SiteCode' AND ServerNALPath Like '$ServerNALPath' AND PackageID = '$($Package.PackageID)'"
$DistPointPkg = Get-WmiObject -Namespace "rootSMSSite_$SiteCode" -Query $Query
Write-Verbose -Message "Refreshing package $($DistPointPkg.PackageID) on $($DistributionPoint.Name)"
$DistPointPkg.RefreshNow = $true
[Void]$DistPointPkg.Put()
}Esto le indicará a System Center Configuration Manager que los paquetes deben actualizarse ahora.
Para su comodidad, publiqué el script en TechNet Gallery:
http://gallery.technet.microsoft.com/Force-SCCM-Distribution-5c243aee