PowerShell: retrieve number of applications in AppPool

I recently came across this post searching for ways to get the active Application Pools. The information provided above was great, but I kept digging to see if there was another way get this information. I was able to find a way to do this through Get-IISSite, which I used the following:

Get-IISSite | Select-Object -ExpandProperty Applications | Select-Object Path,ApplicationPoolName

I tested this on a server that only had one website, but if there are multiple sites on the server, you could also add VirtualDirectories for the Select.

I also had a need to just get a unique list of the Application Pools being used, so I did the following:

$appPoolInfo = Get-IISSite | Select-Object -ExpandProperty Applications | Select-Object Path,ApplicationPoolName

$appPoolInfo | Select-Object -Unique ApplicationPoolName

I dealt with this same issue for many hours until finally arriving at the solution. The answer from D.R. was very helpful but it was not working for me. After some tweaks, I came up with the code below which retrieves the number of applications in an app pool.

I noticed that this part of the code nd @path!='/' threw off the count.

$appPool = "REPLACE ME with a value from your app pool"
@(Get-WebConfigurationProperty "/system.applicationHost/sites/site/application[@applicationPool=`'$appPool`']" "machine/webroot/apphost" -name path).Count

The trick is: PowerShell established so-called "view definition files" which tell PowerShell how to format objects (e.g. whether the object is formatted as a a list or a table, which columns are displayed, etc.). Those files can be found at C:\Windows\System32\WindowsPowerShell\v1.0 and are all ending in .format.ps1xml.

To answer the original question: The file C:\Windows\System32\WindowsPowerShell\v1.0\Modules\WebAdministration\iisprovider.format.ps1xml contains the view definition for the AppPool type which defines a calculated column looking like this:

<TableColumnItem>
 <ScriptBlock>
    $pn = $_.Name
    $sites = get-webconfigurationproperty "/system.applicationHost/sites/site/application[@applicationPool=`'$pn`'and @path='/']/parent::*" machine/webroot/apphost -name name
    $apps = get-webconfigurationproperty "/system.applicationHost/sites/site/application[@applicationPool=`'$pn`'and @path!='/']" machine/webroot/apphost -name path
    $arr = @()
    if ($sites -ne $null) {$arr += $sites}
    if ($apps -ne $null) {$arr += $apps}
    if ($arr.Length -gt 0) {
      $out = ""
      foreach ($s in $arr) {$out += $s.Value + "`n"}
      $out.Substring(0, $out.Length - 1)
    }
  </ScriptBlock>
</TableColumnItem>

This answers why the column itself is not a member of the AppPool type. The second question can be easily answered now extracting the necessary code from the "scriptlet" above:

$applicationsInAppPoolCount = @(Get-WebConfigurationProperty `"/system.applicationHost/sites/site/application[@applicationPool=`'$appPool`'and @path!='/']"` "machine/webroot/apphost" -name path).Count

I ended up with the following Code (basically the same as above, but differently formatted)

$appPools = Get-ChildItem –Path IIS:\AppPools
foreach ($apppool in $apppools) {
  $appoolName = $apppool.Name
  [string] $NumberOfApplications = (Get-WebConfigurationProperty "/system.applicationHost/sites/site/application[@applicationPool='$appoolName']" "machine/webroot/apphost" -name path).Count
  Write-Output "AppPool name: $appoolName has $NumberOfApplications applications"
}