美文网首页
使用powershell管理进程和服务(翻译自官方文档7.1 M

使用powershell管理进程和服务(翻译自官方文档7.1 M

作者: mudssky | 来源:发表于2020-04-03 23:21 被阅读0次

    01.使用process cmdlet管理进程

    001.获取进程信息(Get-Process)

    使用这个命令可以获得进程信息,你也可以指定名字或者进程id来指定获取信息的进程。

    PS> Get-Process -id 0
    
    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
    -------  ------    -----      ----- -----   ------     -- -----------
          0       0        0         16     0               0 Idle
    

    指定属性的时候,如果找不到会报错。

    如果指定名字,可以指定多个,并且支持通配符

    PS> Get-Process -Name ex*
    
    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
    -------  ------    -----      ----- -----   ------     -- -----------
        234       7     5572      12484   134     2.98   1684 EXCEL
        555      15    34500      12384   134   105.25    728 explorer
    

    更复杂一些的命令是加上机器名,并且用规范的格式输出

    PS> Get-Process powershell -ComputerName localhost, Server01, Server02 |
        Format-Table -Property Handles,
            @{Label="NPM(K)";Expression={[int]($_.NPM/1024)}},
            @{Label="PM(K)";Expression={[int]($_.PM/1024)}},
            @{Label="WS(K)";Expression={[int]($_.WS/1024)}},
            @{Label="VM(M)";Expression={[int]($_.VM/1MB)}},
            @{Label="CPU(s)";Expression={if ($_.CPU -ne $()){$_.CPU.ToString("N")}}},
            Id, ProcessName, MachineName -auto
    
    Handles  NPM(K)  PM(K) WS(K) VM(M) CPU(s)  Id ProcessName  MachineName
    -------  ------  ----- ----- ----- ------  -- -----------  -----------
        258       8  29772 38636   130         3700 powershell Server01
        398      24  75988 76800   572         5816 powershell localhost
        605       9  30668 29800   155 7.11    3052 powershell Server02
    

    002.终结进程 (Stop-Process)

    可以使用名字来终结进程。

    PS> Stop-Process -Name Idle
    Stop-Process : Process 'Idle (0)' cannot be stopped due to the following error:
     Access is denied
    At line:1 char:13
    + Stop-Process  <<<< -Name Idle
    

    终结进程的能力取决于你的权限,有些进程无法被终结。

    你也可以选择强制弹出确认提示,这个在你使用通配符匹配的时候会很有用。

    PS> Stop-Process -Name t*,e* -Confirm
    Confirm
    Are you sure you want to perform this action?
    Performing operation "Stop-Process" on Target "explorer (408)".
    [Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
    (default is "Y"):n
    Confirm
    Are you sure you want to perform this action?
    Performing operation "Stop-Process" on Target "taskmgr (4072)".
    [Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
    (default is "Y"):n
    

    复杂一点的进程操作,可以使用where来筛选执行对象,一个进程如果可以进行响应会返回true,可以利用这个性质,终结所有没有响应的应用

    Get-Process | Where-Object -FilterScript {$_.Responding -eq $false} | Stop-Process

    由于Stop-Process没有主机名选项ComputerName,所以远程停止其他电脑的进程,需要通过Invoke-Command来实现

    Invoke-Command -ComputerName Server01 {Stop-Process Powershell}

    003.终结所有其他powershell会话

    PS> Get-Process -Name powershell | Where-Object -FilterScript {$_.Id -ne $PID} | Stop-Process -PassThru
    
    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
    -------  ------    -----      ----- -----   ------     -- -----------
        334       9    23348      29136   143     1.03    388 powershell
        304       9    23152      29040   143     1.03    632 powershell
        302       9    20916      26804   143     1.03   1116 powershell
        335       9    25656      31412   143     1.09   3452 powershell
        303       9    23156      29044   143     1.05   3608 powershell
        287       9    21044      26928   143     1.02   3672 powershell
    

    02.管理服务

    001.获取服务信息

    Get-Service -Name se*
    
    Status   Name               DisplayName
    ------   ----               -----------
    Running  seclogon           Secondary Logon
    Running  SENS               System Event Notification
    Stopped  ServiceLayer       ServiceLayer
    

    远程获取其他电脑的服务信息

    Get-Service -ComputerName Server01
    

    002.获取依赖进程和被依赖服务

    Get-Service有两个在服务管理上比较使用的参数

    DependentServices 参数获取依赖服务的其他服务

    RequiredServices获取一个服务所依赖的服务。

    下面的例子是获取LanmanWorkstation这个服务所依赖的服务。

    PS> Get-Service -Name LanmanWorkstation -RequiredServices
    
    Status   Name               DisplayName
    ------   ----               -----------
    Running  MRxSmb20           SMB 2.0 MiniRedirector
    Running  bowser             Bowser
    Running  MRxSmb10           SMB 1.x MiniRedirector
    Running  NSI                Network Store Interface Service
    

    下面的命令获取依赖LanmanWorkstation的服务

    PS> Get-Service -Name LanmanWorkstation -DependentServices
    
    Status   Name               DisplayName
    ------   ----               -----------
    Running  SessionEnv         Terminal Services Configuration
    Running  Netlogon           Netlogon
    Stopped  Browser            Computer Browser
    Running  BITS               Background Intelligent Transfer Ser...
    

    你甚至可以获取所有有依赖的服务。

    Get-Service -Name * | Where-Object {$_.RequiredServices -or $_.DependentServices} |
      Format-Table -Property Status, Name, RequiredServices, DependentServices -auto
    

    003.停止,开始,挂起,和重启服务

    Stop-Service -Name spooler
    
    Start-Service -Name spooler
    
    Suspend-Service -Name spooler
    
    Restart-Service -Name spooler
    

    03.管理Windows PowerShell Drives

    Windows PowerShell Drives是一种数据存储位置,可以像访问磁盘驱动器一样进行访问。

    里面为你创建了一些驱动器,比如c盘,d盘,还有注册表驱动器,证书驱动器等。

    你也可以创建你自己的驱动器,但是这些驱动器只能在powershell中进行访问。资源管理器或者cmd中无法访问。

    专有名词是PSDrive

    PS> Get-PSDrive
    
    Name       Provider      Root                                   CurrentLocation
    ----       --------      ----                                   ---------------
    A          FileSystem    A:\
    Alias      Alias
    C          FileSystem    C:\                                 ...And Settings\me
    cert       Certificate   \
    D          FileSystem    D:\
    Env        Environment
    Function   Function
    HKCU       Registry      HKEY_CURRENT_USER
    HKLM       Registry      HKEY_LOCAL_MACHINE
    Variable   Variable
    

    使用Get-Command命令查看语法

    PS> Get-Command -Name Get-PSDrive -Syntax
    
    Get-PSDrive [[-Name] <String[]>] [-Scope <String>] [-PSProvider <String[]>] [-V
    erbose] [-Debug] [-ErrorAction <ActionPreference>] [-ErrorVariable <String>] [-
    OutVariable <String>] [-OutBuffer <Int32>]
    

    PSProvider 参数允许你选择特定的provider类型。

    PS> Get-PSDrive -PSProvider FileSystem
    
    Name       Provider      Root                                   CurrentLocation
    ----       --------      ----                                   ---------------
    A          FileSystem    A:\
    C          FileSystem    C:\                           ...nd Settings\PowerUser
    D          FileSystem    D:\
    

    你也可以使用常用的路径操作命令

    PS> Set-Location HKLM:\SOFTWARE
    PS> Push-Location .\Microsoft
    PS> Get-Location
    
    Path
    ----
    HKLM:\SOFTWARE\Microsoft
    

    001.添加新的Windows PowerShell Drives (New-PSDrive)

    创建一个新的 Windows PowerShell drive,需要提供三个参数

    • 驱动器的名字
    • PSProvider,比如文件系统类型或者注册表类型
    • 根路径的位置

    比如创建一个名叫Office的新驱动器,映射一个文件夹,里面用于存放Office应用,

    PS> New-PSDrive -Name Office -PSProvider FileSystem -Root "C:\Program Files\Microsoft Office\OFFICE11"
    
    Name       Provider      Root                                   CurrentLocation
    ----       --------      ----                                   ---------------
    Office     FileSystem    C:\Program Files\Microsoft Offic...
    

    注意:路径是大小写不敏感的。

    Windows PowerShell drive可以简化一些任务,举个例子,一些注册表的键值可能有很长的路径。

    创建powershell驱动器可以简化这些路径

    比如

    PS> New-PSDrive -Name cvkey -PSProvider Registry -Root HKLM\Software\Microsoft\Windows\CurrentVersion
    
    Name       Provider      Root                                   CurrentLocation
    ----       --------      ----                                   ---------------
    cvkey      Registry      HKLM\Software\Microsoft\Windows\...
    

    你可以在其他任何驱动器访问这个新建的驱动器

    cd cvkey:
    

    或者

    PS> Set-Location cvkey: -PassThru
    
    Path
    ----
    cvkey:\
    

    注意这个新建的驱动器只在当前会话中存在,关闭当前powershell窗口,这个新建的驱动器就会丢失。

    如果想要永久保存这个驱动器,可以使用 Export-Console命令导出当前的powershell会话,

    然后使用PowerShell.exe PSConsoleFile参数来导入这个会话文件,或者也可以写入powershell'的profile中。

    002.删除Windows PowerShell Drivess(Remove-PSDrive)

    Remove-PSDrive -Name Office
    

    04.处理网络任务

    001.获取电脑的IP地址

    如果是获取本机的ip地址,执行以下命令

     Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=$true |
      Select-Object -ExpandProperty IPAddress
    

    002.获取IP配置数据

    获取每个网络适配器详细的ip配置信息,执行:

    Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=$true
    

    默认的输出格式比较难以查看,使用Select-Object或者 Format-List来指定显示的属性

    现代TCP/IP 网络上,你可能不会对 IPX或者WINS属性感兴趣,可以排除掉这些属性

    Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=$true |
      Select-Object -ExcludeProperty IPX*,WINS*
    

    003.ping

    可以使用Win32_PingStatus实现ping另一台电脑的功能

    Get-CimInstance -Class Win32_PingStatus -Filter "Address='127.0.0.1'"
    

    一个比较好的信息总结需要显示地址,响应时间和状态码属性,执行Format-Table命令来格式化输出

    Get-CimInstance -Class Win32_PingStatus -Filter "Address='127.0.0.1'" |
      Format-Table -Property Address,ResponseTime,StatusCode -Autosize
    
    Address   ResponseTime StatusCode
    -------   ------------ ----------
    127.0.0.1            0          0
    

    StatusCode 值为0表示一个成功的ping

    你也可以使用数组去ping多台电脑

    '127.0.0.1','localhost','research.microsoft.com' |
      ForEach-Object -Process {
        Get-CimInstance -Class Win32_PingStatus -Filter ("Address='$_'") |
          Select-Object -Property Address,ResponseTime,StatusCode
      }
    

    可以用同样形式的命令ping一个网络的所有子网

    1..254| ForEach-Object -Process {
      Get-CimInstance -Class Win32_PingStatus -Filter ("Address='192.168.1.$_ '") } |
        Select-Object -Property Address,ResponseTime,StatusCode
    

    004.获取网络适配器信息

    Get-CimInstance -Class Win32_NetworkAdapter -ComputerName .
    

    005.给网络适配器更换DNS地址

    需要用到Win32_NetworkAdapterConfigurationSetDNSDomain 方法

    Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=$true |
      ForEach-Object -Process { $_.SetDNSDomain('fabrikam.com') }
    

    IPEnabled属性是必要的,因为即使再一个只使用TCP/IP的网络上也会有一些不是TCP/IP的网络适配器。

    也可以使用where进行过滤

    Get-CimInstance -Class Win32_NetworkAdapterConfiguration |
      Where-Object {$_.IPEnabled} |
        ForEach-Object -Process {$_.SetDNSDomain('fabrikam.com')}
    

    006.执行DHCP配置任务

    寻找开启DHCP的网络适配器

    Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter "DHCPEnabled=$true"
    

    再配置IP设置有问题的配置器

    Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled=$true and DHCPEnabled=$true"
    

    获取DHCP属性

    因为DHCP相关的属性通常是DHCP开头的,所以

    Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter "DHCPEnabled=$true" |
      Format-Table -Property DHCP*
    

    开启每个适配器的DHCP

    Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=$true |
      ForEach-Object -Process {$_.EnableDHCP()}
    

    可以用Filter 筛选掉那些已经启动DHCP的。

    在特定适配器上Releasing 或者 Renewing DHCP协议

    Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled=$true and DHCPEnabled=$true" |
      Where-Object {$_.DHCPServer -contains '192.168.1.254'} |
        ForEach-Object -Process {$_.ReleaseDHCPLease()}
    

    在所有适配器上Releasing 或者 Renewing DHCP协议

    通过列出所有WMI类,然后根据名字选择需要的类,就可以返回一个Win32_NetworkAdapterConfiguration 类而不是实例。

    Get-CimInstance -List | Where-Object {$_.Name -eq 'Win32_NetworkAdapterConfiguration'}
    

    你可以把整个命令当作一个class,然后调用ReleaseDHCPAdapterLease 方法,

    (Get-CimInstance -List |
      Where-Object {$_.Name -eq 'Win32_NetworkAdapterConfiguration'}).ReleaseDHCPLeaseAll()
    

    同样的形式,可以调用RenewDHCPLeaseAll 方法

    007.创建网络共享

    (Get-CimInstance -List |
      Where-Object {$_.Name -eq 'Win32_Share'}).Create(
        'C:\temp','TempShare',0,25,'test share of the temp folder'
      )
    

    windows平台也可以使用 net share命令

    net share tempshare=c:\temp /users:25 /remark:"test share of the temp folder"
    

    008.移除网络共享

    (Get-CimInstance -Class Win32_Share -Filter "Name='TempShare'").Delete()
    

    or(windows only)

    net share tempshare /delete
    

    009.连接windows可访问网络驱动器

    之前讲了New-PSDrive创建一个powershell驱动器,如果需要通过网络访问驱动器可以使用WScript.Network COM object

    执行以下命令把\FPS01\users 映射到b驱动器

    (New-Object -ComObject WScript.Network).MapNetworkDrive('B:', '\\FPS01\users')
    

    windows平台下可以使用net use

    net use B: \\FPS01\users
    

    05.软件安装

    001.列出windows installer应用

    Get-CimInstance -Class Win32_Product |
      Where-Object Name -eq "Microsoft .NET Core Runtime - 2.1.5 (x64)"
    

    这条命令执行还是比较慢的。

    Get-CimInstance -Class Win32_Product |
      Where-Object Name -eq "Microsoft .NET Core Runtime - 2.1.5 (x64)" |
        Format-List -Property *
    

    002.列出所有能卸载的应用

    因为大多数标准应用都注册了卸载程序,可以从下面这个注册表里面找到

    New-PSDrive -Name Uninstall -PSProvider Registry -Root HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
    

    查看卸载程序的数目

    (Get-ChildItem -Path Uninstall:).Count

    列表用变量保存

    $UninstallableApplications = Get-ChildItem -Path Uninstall:
    

    显示名称

    $UninstallableApplications | ForEach-Object -Process { $_.GetValue('DisplayName') }
    

    查询特定

    $UninstallableApplications | Where-Object -FilterScript {
      $_.GetValue("DisplayName") -eq "Microsoft Silverlight"
    }
    

    003.安装应用

    可以使用Win32_Product类安装应用,当然需要管理员权限。

    Invoke-CimMethod -ClassName Win32_Product -MethodName Install -Arguments @{PackageLocation='\\AppSrv\dsp\NewPackage.msi'}
    

    004.删除应用

    Get-CimInstance -Class Win32_Product -Filter "Name='ILMerge'" | Invoke-CimMethod -MethodName Uninstall
    

    可以通过删除字符串找到可以删除的程序

    Get-ChildItem -Path Uninstall: | ForEach-Object -Process { $_.GetValue('UninstallString') }
    
    Get-ChildItem -Path Uninstall: |
        Where-Object -FilterScript { $_.GetValue('DisplayName') -like 'Win*'} |
            ForEach-Object -Process { $_.GetValue('UninstallString') }
    

    005.升级Windows Installer应用

    Get-CimInstance -Class Win32_Product -Filter "Name='OldAppName'" |
      Invoke-CimMethod -MethodName Upgrade -Arguments @{PackageLocation='\\AppSrv\dsp\OldAppUpgrade.msi'}
    

    06.解码正在运行的powershell脚本

    有时,我们会运行一些占用大量资源的powershell程序。当由多个powershell程序运行的时候,很难判断哪个程序出了问题。下面我们就展示如何从一个运行的powershell进程中解码代码块

    001.创建一个运行时长比较长的进程

    下面这个程序会每分钟输出一个数字,持续10分钟

    powershell.exe -Command {
        $i = 1
        while ( $i -le 10 )
        {
            Write-Output -InputObject $i
            Start-Sleep -Seconds 60
            $i++
        }
    }
    

    002.查看进程

    执行的命令体会被存储在Win32_Process类的属性上,并且命令被编码了。依据这一信息我们可以用下面的步骤反混淆

    以管理员模式打开powershell,执行下面的命令

    获取到编码过的命令

    $powerShellProcesses = Get-CimInstance -ClassName Win32_Process -Filter 'CommandLine LIKE "%EncodedCommand%"'
    

    下面的步骤创建一个传统的powershell对象包括进程id和编码的命令

    $commandDetails = $powerShellProcesses | Select-Object -Property ProcessId,
    @{
        name       = 'EncodedCommand'
        expression = {
            if ( $_.CommandLine -match 'encodedCommand (.*) -inputFormat' )
            {
                return $matches[1]
            }
        }
    }
    

    然后编码的命令就能被解码了。

    下面的代码片段,遍历命令对象,解码被编码的命令,将解码后的命令加回该对象,供进一步研究

    $commandDetails | ForEach-Object -Process {
        # Get the current process
        $currentProcess = $_
    
        # Convert the Base 64 string to a Byte Array
        $commandBytes = [System.Convert]::FromBase64String($currentProcess.EncodedCommand)
    
        # Convert the Byte Array to a string
        $decodedCommand = [System.Text.Encoding]::Unicode.GetString($commandBytes)
    
        # Add the decoded command back to the object
        $commandDetails |
            Where-Object -FilterScript { $_.ProcessId -eq $_.ProcessId } |
            Add-Member -MemberType NoteProperty -Name DecodedCommand -Value $decodedCommand
    }
    $commandDetails[0]
    

    查看会是下面的样子。

    ProcessId      : 8752
    EncodedCommand : IAAKAAoACgAgAAoAIAAgACAAIAAkAGkAIAA9ACAAMQAgAAoACgAKACAACgAgACAAIAAgAHcAaABpAGwAZQAgACgAIAAkAGkAIAAtAG
                     wAZQAgADEAMAAgACkAIAAKAAoACgAgAAoAIAAgACAAIAB7ACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABXAHIAaQB0AGUALQBP
                     AHUAdABwAHUAdAAgAC0ASQBuAHAAdQB0AE8AYgBqAGUAYwB0ACAAJABpACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABTAHQAYQ
                     ByAHQALQBTAGwAZQBlAHAAIAAtAFMAZQBjAG8AbgBkAHMAIAA2ADAAIAAKAAoACgAgAAoAIAAgACAAIAAgACAAIAAgACQAaQArACsA
                     IAAKAAoACgAgAAoAIAAgACAAIAB9ACAACgAKAAoAIAAKAA==
    DecodedCommand :
                         $i = 1
    
                         while ( $i -le 10 )
    
                         {
    
                             Write-Output -InputObject $i
    
                             Start-Sleep -Seconds 60
    
                             $i++
    
                         }
    

    相关文章

      网友评论

          本文标题:使用powershell管理进程和服务(翻译自官方文档7.1 M

          本文链接:https://www.haomeiwen.com/subject/wnxrphtx.html