Saturday, September 29, 2012

Powershell, WMI, rapidfailprotection, and Set-WmiInstance

Recently, I've been having to admin IIS7+ with WMI. I was pretty comfortable reading WMI data with Powershell, but the need to write data just hadn't come up. I figured as easy as it was in C#, it would be even easier with Powershell.

For the most part, it is. There's lots of examples on how to do it.

There's other settings which aren't so straightforward, though. Application pool rapidFailProtection was the one that led me on my investigation. It's contained in an EmbeddedObject, which isn't really a WMI object. For example, it has no __PATH.

Setting it directly didn't work, and neither did Put().

The trick is to put the EmbeddedObject into a temporary variable, SetPropertyValue on the temp variable, and pass the temp variable back as an argument to Set-WmiInstance.
$creds = Get-Credential
$ComputerName = "target.example.com"  
$appPool = (Get-WmiObject -Namespace "root\WebAdministration" `
            -Class "ApplicationPool" `
            -ComputerName $ComputerName `
            -Credential $creds `
            -Authentication PacketPrivacy | `
            where { $_.Name -eq "DefaultAppPool" })
            
if( $null -ne $appPool )
{
    write-host $appPool.Name
    $failureNode = $appPool.Failure
    $failureNode.SetPropertyValue( "RapidFailProtection", $false )

    Set-WmiInstance `
        -InputObject $appPool `
        -Arguments @{ failure = $failureNode }
}

(Get-WmiObject -Namespace "root\WebAdministration" `
            -Class "ApplicationPool" `
            -ComputerName $ComputerName `
            -Credential $creds `
            -Authentication PacketPrivacy | `
            where { $_.Name -eq "DefaultAppPool" }).Failure

If you examine the WMI class you created at the beginning of the script, you won't see the change. Refreshing from the source (or just looking on the server) shows the updated value.