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

[玩转系统] 使用 CIM 搜索 PowerShell

作者:精品下载站 日期:2024-12-14 08:03:40 浏览:14 分类:玩电脑

使用 CIM 搜索 PowerShell


昨天我分享了一个脚本,您可以使用它来清点 Windows PowerShell 和 PowerShell 7 安装的系统。这应该适用于大多数使用提供的安装程序安装 PowerShell 7 的人。但是,正如我不止一次指出的那样,这不会检测到任何侧面加载或带外安装。我在上一篇文章中提到过这一点。我认为您能做的最好的事情就是搜索 pwsh.exe 的硬盘驱动器实例。但我们不想进行强力递归目录搜索。相反,我将使用 Get-CimInstance。

Get-CimInstance -ClassName CIM_Logicalfile -Filter "filename='pwsh' AND extension = 'exe' AND drive='C:'"

我将搜索限制为驱动器 C 以加快速度。这种类型的搜索可以找到稳定安装和预览安装。

[玩转系统] 使用 CIM 搜索 PowerShell

这为我提供了与之前相同的信息以及更多信息。我仍然可以使用 Get-Command 以相同的方式搜索 Windows PowerShell。

剧本

这是修改后的脚本。

#requires -version 5.1

[cmdletbinding()]
Param(
    [Parameter(HelpMessage = "Specify the drive to search for instances of pwsh.exe")]
    [ValidatePattern("^[c-zC-Z]$")]
    [string]$Drive = "C"
)

#a private function to shorten filenames
Function _shortName {
    Param($path)

    $parts = $path.split("\")
    $out = foreach ($part in $parts) {
        if ($part -match "\s") {
            "{0}~1" -f $part.Substring(0, 6)
        }
        else {
            $part
        }
    }

    $out -join "\"
}

Write-Verbose "Searching for PowerShell installations on $([System.Environment]::MachineName)"
$os = (Get-CimInstance -ClassName Win32_OperatingSystem -Property Caption).caption

#region Windows Powershell
Try {
    Write-Verbose "Testing for Windows PowerShell"
    $cmd = Get-Command -Name powershell.exe -ErrorAction stop
    if ($cmd) {
        Write-Verbose "Using $($cmd.path)"
        #need to run Powershell.exe to get $PSVersion
        $psh = &$cmd.path -nologo -noprofile -command { Get-Host }

        #test for PowerShell 2.0 engine or feature

        Write-Verbose "Testing for Windows PowerShell 2.0 engine or feature"

        #get computersystem roles to determine if running on a server or client
        #assuming operating system caption uses 'Server'

        if ($os.caption -match "server") {
            Write-Verbose "Running Get-WindowsFeature"
            $f = Get-WindowsFeature PowerShell-V2
        }
        else {
            Write-Verbose "Running Get-WindowsOptionalFeature"
            $f = Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root
        }

        if ($f.installed -OR $f.State -eq 'Enabled') {
            $comment = "Windows PowerShell 2.0 feature enabled or installed"
        }
        else {
            $comment = ""
        }
        #the install date will reflect the last time the OS was updated or installed
        [pscustomobject]@{
            PSTypeName      = "PSInstallInfo"
            Name            = $cmd.Name
            Path            = $cmd.source
            PSVersion       = $psh.Version
            Installed       = (Get-Item $cmd.source).CreationTime
            Comments        = $comment
            Computername    = [System.Environment]::MachineName
            OperatingSystem = $os
        }
        Remove-Variable cmd

    } #$cmd found
} #try
Catch {
    #this should never happen
    Write-Verbose "Windows PowerShell not installed on $([Environment]::MachineName)."
}
#endregion

#region PowerShell 7
Write-Verbose "Testing for PowerShell 7 including preview builds"
$pwsh = Get-CimInstance -ClassName CIM_Logicalfile -Filter "filename='pwsh' AND extension = 'exe' AND drive='$($drive):'"
if ($pwsh) {
    Foreach ($item in $pwsh) {

        if ($item.path -match 'preview') {
            $comment = "Preview"
        }
        else {
            $comment = ""
        }

        #test for SSH
        if (Test-Path $env:programdata\ssh\sshd_config ) {
            #get short name
            $short = _shortName $item.EightDotThreeFileName
            Write-Verbose "Testing for an SSH subsystem using $short"
            $ssh = Get-Content $env:programdata\ssh\sshd_config | Select-String $($short -replace "\", "\")
            #'(?<=powershell\s).*pwsh.exe'
            if ($ssh.matches.value -eq $short) {
                $comment += " SSH configured"
            }
        }

        [pscustomobject]@{
            PSTypeName      = "PSInstallInfo"
            Name            = Split-Path $item.name -Leaf
            Path            = Split-Path $item.name
            PSVersion       = $item.version
            Installed       = $item.InstallDate
            Comments        = $comment.Trim()
            Computername    = [System.Environment]::MachineName
            OperatingSystem = $os
        }

    }
}
#endregion

#end of script

变化

我在此版本中做了一些更改。首先,我决定不将 PowerShell 2.0 引擎视为单独的版本。您对 5.1 和 2.0 使用相同的 powershell.exe 版本。相反,我在评论中反映了 2.0 引擎的状态。我还采用了不同的 SSH 方法。我没有测试 SSH 是否已安装并运行,而是检查 sshd_config 文件中是否存在 PowerShell 子系统。这使您可以在 PowerShell 中使用 SSH 远程处理进行连接。

这需要一些操作,因为来自 Windows 的长文件名在 sshd_config 文件中被截断。因此,我不是搜索 C:\Program Files\PowerShell\7\pwsh.exe”,而是寻找“c:\progra~1\powershell\7\pwsh.exe”。我编写了一个简短的辅助函数来转换路径。我意识到这并不是万无一失的,但它适用于我的 SSH 安装。

这是默认的本地输出。

[玩转系统] 使用 CIM 搜索 PowerShell

和以前一样,您可以使用远程处理来清点其他服务器和桌面。

$c = Invoke-Command -FilePath C:\scripts\Get-PSExeFile.ps1 -ComputerName win10,srv1,srv2 -HideComputerName | sort computername

[玩转系统] 使用 CIM 搜索 PowerShell

你喜欢那个吗?我修改了ps1xml文件的格式。

<!--
Format type data generated 07/13/2021 12:14:45 by PROSPERO\Jeff

This file was created using the New-PSFormatXML command that is part
of the PSScriptTools module.

https://github.com/jdhitsolutions/PSScriptTools
-->
<Configuration>
  <ViewDefinitions>
    <View>
      <!--Created 07/13/2021 12:14:45 by PROSPERO\Jeff-->
      <Name>default</Name>
      <ViewSelectedBy>
        <TypeName>PSInstallInfo</TypeName>
      </ViewSelectedBy>
      <GroupBy>
        <ScriptBlock>
        if ($host.name -match "console|code|serverremotehost") {
          "{0} [$([char]27)[3m{1}$([char]27)[0m]" -f $_.Computername,$_.OperatingSystem
        }
        else {
          "{0} [{1}]" -f $_.Computername,$_.OperatingSystem
        }
        </ScriptBlock>
        <Label>Computername</Label>
      </GroupBy>
      <TableControl>
        <!--Delete the AutoSize node if you want to use the defined widths
        <AutoSize />.-->
        <TableHeaders>
          <TableColumnHeader>
            <Label>Name</Label>
            <Width>19</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>PSVersion</Label>
            <Width>16</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
           <TableColumnHeader>
            <Label>Installed</Label>
            <Width>12</Width>
            <Alignment>left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>Comments</Label>
          </TableColumnHeader>
        </TableHeaders>
        <TableRowEntries>
          <TableRowEntry>
            <TableColumnItems>
              <TableColumnItem>
                <PropertyName>Name</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <ScriptBlock>
                if (($host.name -match "console|code|serverremotehost") -AND ($_.path -match "preview")) {
                  "$([char]27)[38;5;219m$($_.PSVersion)$([char]27)[0m"
                }
                else {
                  $_.PSVersion
                }
                </ScriptBlock>
              </TableColumnItem>
              <TableColumnItem>
                <ScriptBlock>$_.Installed.ToShortDateString()</ScriptBlock>
              </TableColumnItem>
              <TableColumnItem>
               <ScriptBlock>
                if (($host.name -match "console|code|serverremotehost") -AND ($_.comments-match "SSH configured")) {
                  <!-- replace SSH Detected with an ANSI sequence-->
                  $_.comments -replace "SSH configured","$([char]27)[1;38;5;155mSSH configured$([char]27)[0m"
                }
                else {
                  $_.comments
                }
                </ScriptBlock>
              </TableColumnItem>
            </TableColumnItems>
          </TableRowEntry>
        </TableRowEntries>
      </TableControl>
    </View>
  </ViewDefinitions>
</Configuration>

概括

此时,您应该有多种选择。希望其中之一能够满足您的需求。或者随意剪切所需的部分并将其粘贴到您自己的工具中。如果您采用这种方法,我希望您能分享您的工作。随时欢迎提问和评论。享受。

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

取消回复欢迎 发表评论:

关灯