PowerShell Format Dosyalarını Kolay Yoluyla


Ne zaman PowerShell betiği oluşturmayı öğretsem veya sunum yapsam, her zaman nesneleri ardışık düzene yazmaktan bahsediyorum. Çoğu zaman PowerShell'in komutunuzun çıktısını mümkün olan en iyi şekilde biçimlendirmesine ve görüntülemesine izin verebilirsiniz. Ancak, meseleyi kendi elinize almak ve özel çıktılar oluşturmak isteyebilirsiniz. Örneğin, Get-Process PowerShell çalıştırmanız biçimlendirilmiş bir tablo görüntülediğinde. Ancak Get-Member ile gördüğünüz altta yatan nesnenin görüntülenmesinin gerekli olmadığını biliyorsunuz. PowerShell, İşlem nesneleri için varsayılan bir görünüm tanımlar. Aynı şeyi komutlarınızla da yapabilirsiniz.

Özel Çıktı Oluşturma

Burada, bir dizi WMI sınıfından türetilen özelliklere sahip özel bir nesneyi ardışık düzene yazan nispeten basit bir komut dosyası verilmiştir.

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

Özel nesnenin parçası olarak özel bir tür adı tanımlıyorum.

Diyelim ki varsayılan çıktının liste yerine tablo olmasını tercih ediyorum. Bunun için format.ps1xml dosyasında saklanan bir tablo tanımı gerekir. Bu dosyaların oluşturulması zor olabilir. $PSHome\DotnetTypes.format.ps1xml gibi mevcut bir dosyada bir şey bulurdum ve bunu daha sonra güncellediğim yeni bir dosyaya kopyalardım. Ama artık çok daha iyi bir çözümüm var.

Yeni-PSFormatXML

PSScriptTools modülüm (PowerShell Galerisinden yükleyebilirsiniz) artık New-PSFormatXML adlı bir komut içeriyor. Komut, bir nesneyi analiz etmek ve varsayılan olarak tüm özelliklerin tablo görünümünü oluşturmak için tasarlanmıştır; ancak hangi özelliklerin dahil edileceğini belirtebilirsiniz. format.ps1xml dosyası tabloyu otomatik olarak boyutlandıracaktır ancak yönergeyi kaldırabilir ve en iyi tahmin olan genişlikleri kullanabilirsiniz. Yeni bir görünüm tanımlarken biraz deneme yanılma bekleyin.

Yeni bir dosya oluşturmak bu kadar kolaydır:

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

Bir nesnenin yalnızca tek bir örneğine ihtiyacınız vardır. Birden çok nesneyi New-PSFormatXML'e yönlendirebilirsiniz ancak sonraki nesneler göz ardı edilecektir. Komut şuna benzer bir xml dosyası oluşturacaktır:

<?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>

Buradan dosyayı gerektiği gibi düzenleyebilirim. Ancak tüm özellikleri bir tabloda görüntülemekten mutlu olduğum için PowerShell'i bu bilgilerle güncelleyeceğim.

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

Artık işlevimi çalıştırdığımda varsayılan olarak bir tablo görüntüsü alıyorum.

Daha Fazla Görünüm Ekleme

Ayrıca ek görünümler de oluşturabilirim.

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

Yine görünümü değiştiriyorum, hatta özel özellikler ekliyorum. İşte revize edilmiş format dosyam.

<?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>

Bu görünümde, adından 'Microsoft'u çıkaran işletim sistemi özelliğini tanımlamak için bir komut dosyası bloğu kullanıyorum. Kullanmak için format verilerini güncelliyorum ve komutu görünüm adını belirten Format-Table'a aktarıyorum.

Güzelleştir

Artık fonksiyonlarınızdan güzel veya en azından anlamlı çıktılar almamanız için hiçbir neden yok. İşlem hattına özel nesneler yazıyorsanız, bir tür adı tanımladığınız sürece biçimlendirme yönergelerini oluşturmak artık çok daha kolay olacaktır. Modül manifestinizde FormatsToProcess bölümünde format.ps1xml dosyalarınızı belirtin.

Umarım bunu PowerShell araç kutunuza faydalı bir eklenti olarak bulursunuz. Bunun artık işimde her zaman kullanacağım bir şey olduğunu biliyorum.

İlgili makaleler