当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] PowerShell 格式化文件的简单方法

作者:精品下载站 日期:2024-12-14 07:54:38 浏览:15 分类:玩电脑

PowerShell 格式化文件的简单方法


每当我教授或演示 PowerShell 脚本编写时,我总是谈论将对象写入管道。大多数时候,您只需让 PowerShell 尽可能格式化并显示命令的输出即可。但是,您可能希望亲自处理并创建自定义输出。例如,当您运行 Get-Process PowerShell 时,会显示一个格式化的表。但您知道,显示的内容不一定是您使用 Get-Member 看到的底层对象。 PowerShell 定义了 Process 对象的默认视图。您可以使用命令执行相同的操作。

创建自定义输出

这是一个相对简单的脚本,它将自定义对象写入管道,该对象具有派生自多个 WMI 类的属性。

Function Get-SysInfo {

    [cmdletbinding()]

    Param(
        [Parameter(Position = 0, ValueFromPipeline)]
        [ValidateNotNullorEmpty()]
        [string]$Computername = $env:computername,
        [PSCredential]$Credential
    )

    Begin {
        $cimParams = @{
            Classname   = ""
            CimSession  = ""
            Property    = "*"
            ErrorAction = "stop"
        }
    }

    Process {
        Try {
            $sess = New-CimSession @PSBoundParameters
            $cimParams.cimSession = $sess
        }
        Catch {
            Throw $_
        }

        $cimParams.Classname = "Win32_Operatingsystem"
        $cimParams.Property = "CSName", "Caption","Version"
        Try {
            $os = Get-CimInstance @cimParams
        }
        Catch {
            Throw $_
        }
        $cimParams.Classname = "Win32_Computersystem"
        $cimParams.Property = "Manufacturer", "Model"
        $cs = Get-CimInstance @cimParams

        $cimParams.Classname = "Win32_Process"
        $cimParams.Property = "Name"
        $procs = Get-CimInstance @cimParams

        $cimParams.Classname = "Win32_Service"
        $cimParams.Filter = "State = 'running'"
        $running = Get-Ciminstance @cimParams

        [PSCustomobject]@{
            PSTypeName   = "mySysInfo"
            Computername = $os.CSName
            OS           = $os.Caption
            Version      = $os.Version
            System       = ("{0} {1}" -f $cs.Manufacturer.Trim(), $cs.Model.Trim())
            Services     = $Running.Count
            Processes    = $Procs.count
        }

        $cimParams.remove("filter")
        Remove-CimSession $sess

    } #close Process
    End {
        #not used
    }
} #close function

[玩转系统] PowerShell 格式化文件的简单方法

我将自定义类型名称定义为自定义对象的一部分。

[玩转系统] PowerShell 格式化文件的简单方法

假设我更喜欢默认输出为表格而不是列表。这将需要存储在 format.ps1xml 文件中的表定义。创建这些文件可能很棘手。我曾经在现有文件(例如 $PSHome\DotnetTypes.format.ps1xml)中查找某些内容,并将其复制到一个新文件中,然后更新该文件。但现在我有一个更好的解决方案。

新PSFormatXML

我的 PSScriptTools 模块(可以从 PowerShell 库安装)现在包含一个名为 New-PSFormatXML 的命令。该命令旨在分析对象并默认创建所有属性的表视图,尽管您可以指定要包含哪些属性。 format.ps1xml 文件将自动调整表格大小,但您可以删除该指令并使用最佳猜测的宽度。定义新视图时需要进行一些尝试和错误。

创建新文件就像这样简单:

Get-SysInfo | New-PSFormatXML -Path .\mySysInfo.format.ps1xml

您只需要一个对象的单个实例。您可以通过管道将多个对象传递给 New-PSFormatXML,但后续对象将被忽略。该命令将生成一个如下所示的 xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<!--
format type data generated 02/18/2019 12:19:49
by BOVINE320\Jeff
-->
<Configuration>
  <ViewDefinitions>
    <View>
      <!--Created 02/18/2019 12:19:49 by BOVINE320\Jeff-->
      <Name>default</Name>
      <ViewSelectedBy>
        <TypeName>mySysInfo</TypeName>
      </ViewSelectedBy>
      <TableControl>
        <!--Delete the AutoSize node if you want to use the defined widths.-->
        <AutoSize />
        <TableHeaders>
          <TableColumnHeader>
            <Label>Computername</Label>
            <Width>15</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>OS</Label>
            <Width>27</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>Version</Label>
            <Width>13</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>System</Label>
            <Width>20</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>Services</Label>
            <Width>11</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>Processes</Label>
            <Width>12</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
        </TableHeaders>
        <TableRowEntries>
          <TableRowEntry>
            <TableColumnItems>
              <!--
            By default the entries use property names, but you can replace them with scriptblocks.
            <Scriptblock>$_.foo /1mb -as [int]</Scriptblock>
-->
              <TableColumnItem>
                <PropertyName>Computername</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>OS</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Version</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>System</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Services</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Processes</PropertyName>
              </TableColumnItem>
            </TableColumnItems>
          </TableRowEntry>
        </TableRowEntries>
      </TableControl>
    </View>
  </ViewDefinitions>
</Configuration>

从这里我可以根据需要编辑文件。但由于我很乐意在表中显示所有属性,因此我将使用此信息更新 PowerShell。

Update-FormatData -AppendPath .\mySysInfo.format.ps1xml

现在,当我运行我的函数时,默认情况下会显示一个表格。

[玩转系统] PowerShell 格式化文件的简单方法

添加更多视图

我还可以创建其他视图。

Get-SysInfo | New-PSFormatXML -Path .\mySysInfo.format.ps1xml -Properties "Computername","OS","Version" -ViewName OS -Append

我再次修改视图,甚至添加自定义属性。这是我修改后的格式文件。

<?xml version="1.0" encoding="UTF-8"?>
<!--
format type data generated 02/18/2019 12:30:50
by BOVINE320\Jeff
-->
<Configuration>
  <ViewDefinitions>
    <View>
      <!--Created 02/18/2019 12:30:50 by BOVINE320\Jeff-->
      <Name>default</Name>
      <ViewSelectedBy>
        <TypeName>mySysInfo</TypeName>
      </ViewSelectedBy>
      <TableControl>
        <!--Delete the AutoSize node if you want to use the defined widths.-->
        <AutoSize />
        <TableHeaders>
          <TableColumnHeader>
            <Label>Computername</Label>
            <Width>15</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>OS</Label>
            <Width>27</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>Version</Label>
            <Width>13</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>System</Label>
            <Width>20</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>Services</Label>
            <Width>11</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>Processes</Label>
            <Width>12</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
        </TableHeaders>
        <TableRowEntries>
          <TableRowEntry>
            <TableColumnItems>
              <!--
            By default the entries use property names, but you can replace them with scriptblocks.
            <Scriptblock>$_.foo /1mb -as [int]</Scriptblock>
-->
              <TableColumnItem>
                <PropertyName>Computername</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>OS</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Version</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>System</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Services</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Processes</PropertyName>
              </TableColumnItem>
            </TableColumnItems>
          </TableRowEntry>
        </TableRowEntries>
      </TableControl>
    </View>
    <View>
      <!--Created 02/18/2019 12:31:00 by BOVINE320\Jeff-->
      <Name>OS</Name>
      <ViewSelectedBy>
        <TypeName>mySysInfo</TypeName>
      </ViewSelectedBy>
      <TableControl>
        <TableHeaders>
          <TableColumnHeader>
            <Label>Computername</Label>
            <Width>15</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>OS</Label>
            <Width>40</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>Version</Label>
            <Width>13</Width>
            <Alignment>right</Alignment>
          </TableColumnHeader>
        </TableHeaders>
        <TableRowEntries>
          <TableRowEntry>
            <TableColumnItems>
              <!--
            By default the entries use property names, but you can replace them with scriptblocks.
            <Scriptblock>$_.foo /1mb -as [int]</Scriptblock>
-->
              <TableColumnItem>
                <PropertyName>Computername</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <Scriptblock>$($_.OS -replace "^Microsoft","").trim()</Scriptblock>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Version</PropertyName>
              </TableColumnItem>
            </TableColumnItems>
          </TableRowEntry>
        </TableRowEntries>
      </TableControl>
    </View>
  </ViewDefinitions>
</Configuration>

在此视图中,我使用脚本块来定义从名称中删除“Microsoft”的操作系统属性。要使用,我更新格式数据并将命令通过管道传输到指定视图名称的 Format-Table。

[玩转系统] PowerShell 格式化文件的简单方法

让它变得漂亮

现在,您的函数没有理由没有漂亮的或至少有意义的输出。如果您将自定义对象写入管道,只要定义类型名,现在创建格式化指令应该更容易。在模块清单中,在 FormatsToProcess 部分中指定 format.ps1xml 文件。

我希望您发现这是对您的 PowerShell 工具箱的有用补充。我知道这是我现在在工作中会一直使用的东西。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯