如何将 IIS AppPools 的应用程序放入数组?

Gür*_*kan 4 windows iis powershell

要查看所有池、它们的状态及其内部应用程序IIS:\AppPools\,我在 PowerShell 中使用以下命令:

Get-ChildItem –Path IIS:\AppPools\
Run Code Online (Sandbox Code Playgroud)

该命令的输出分为 3 列,名为“ Name ”、“ State ”和“ Applications ”;它看起来像这个例子:

名称状态应用程序
---- ----- ------------
DefaultAppPool 启动项
另一个应用程序池启动 /item/item
另一个 AppPool2 启动 /item
AppPool XYZ 已启动项目 1
                                      第 2 项
                                      第 3 项
...

我此时的尝试是将上面命令的输出存储到一个数组中以供以后处理;因此我在 PowerShell 中编写了以下代码:(我注释了每一步以便更好地理解)

Import-Module WebAdministration

# This array contains a hash table with the output of
# the command "Get-ChildItem –Path IIS:\AppPools\":
$MY_IIS_APPLICATION_POOL = @{};

# "$COUNT" contains index number for each hash table in
# "$MY_IIS_APPLICATION_POOL"; It'll increased during
# the foreach-loop at its end:
$COUNT = 0;

# Looping each record/line of the command, to get the
# needed informations out of the several columns:
foreach ($RECORD in (Get-ChildItem –Path IIS:\AppPools\)) {
  # Getting the needed records of each line:
  $POOL_NAME   = $RECORD.Name;
  $POOL_STATUS = $RECORD.State;
  $POOL_APPS   = "";

  # If there are more items in column "Applications":
  if ($RECORD.Applications -is [array]) {
    foreach ($APP in $RECORD.Applications) {
      $POOL_APPS = ($APP.ToString() + "," + $POOL_APPS);
    }
  } elseif ($RECORD.Applications -eq $NULL) {
    # Otherwise, if value is empty:
    $POOL_APPS = "---";
  } else {
    # Or if column contains only one value:
    $POOL_APPS = $RECORD.Applications.ToString();
  }

  # Defining Hash-Table in $MY_IIS_APPLICATION_POOL:
  $MY_IIS_APPLICATION_POOL[$COUNT] = @{
    'Name'   = $POOL_NAME;
    'Status' = $POOL_STATUS;
    'Apps'   = $POOL_APPS;
  };

  # Increase array index number for next hash table:
  $COUNT++;
}
Run Code Online (Sandbox Code Playgroud)

这很有效 - 我可以通过这个方案$MY_ARRAY[0...9].Name或通过$MY_ARRAY[0...9].Status. 但是我通过获取“应用程序”列来获得空值:$MY_ARRAY[0...9].Apps始终为空。

那么有人知道如何从“应用程序”列中获取值吗?

Mik*_*ank 5

原因Applications总是为空是因为这实际上不是正在返回的对象上的属性。该数据是由webadministration 模块中的输出格式化程序在控制台输出中创建的。

如果将应用程序池对象通过管道传输到Get-Member. 您会注意到它Applications不作为成员存在。如果您从中获取完整的类型名称Get-Member

Microsoft.IIs.PowerShell.Framework.ConfigurationElement#system.applicationHost/applicationPools#add
Run Code Online (Sandbox Code Playgroud)

您可以前往 webadministration 模块仔细查看。通常你会在C:\Windows\System32\WindowsPowerShell\v1.0\Modules\WebAdministration

在该模块中,您会找到一个名为的文件iisprovider.format.ps1xml,用于处理输出格式。如果您打开它并搜索类型名称,您将找到正在运行以生成您在Applications列中看到的输出的代码。表列未命名,因此您只需数到第三列即可找到它。它看起来像这样。

<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>
Run Code Online (Sandbox Code Playgroud)

您可以通过管道将输出从Get-ChildItem –Path IIS:\AppPools\to Out-Stringlike$appPoolText = Get-ChildItem –Path IIS:\AppPools\ | Out-String然后解析它,但这似乎需要做很多工作。对于我的使用,我只是将格式化程序代码转换为我可以使用的函数。

function GetAppsInPool($pn) {
    $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)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在技术上使用它Select-Object来创建一个具有计算属性的内联自定义对象,该对象看起来像您希望的那样。就像是

Get-ChildItem IIS:\AppPools\ | select Name,State,@{n='Applications';e={GetAppsInPool -pn $_.Name}}