ค้นหาเว็บไซต์

ความสนุกในการสร้างเครื่องมือ PowerShell เพิ่มเติม


ดังนั้นงานทั่วไปคือการค้นหาบริการที่ตรงกับสถานะบางอย่าง เช่น ทำงานหรือหยุดทำงาน คุณคงเคยเห็นสำนวนนี้:

get-service -computername server01 | where {$_.status -eq 'running'}

ไม่ใช่คำสั่งที่ยุ่งยากที่สุดในการพิมพ์ แต่ถึงแม้ฉันจะพิมพ์ผิดและต้องแก้ไข หากนี่เป็นงานทั่วไป ทำไมไม่สร้างเครื่องมือที่ใช้งานง่ายล่ะ

#requires -version 3.0

Function Get-MyService {
 <# 
 .Synopsis
 Get services by status.
 .Description
 This is a proxy version of Get-Service. The only real change is that you can specify services by their status. The default is to get all running services.
 .Notes
 Created:	9/11/2014 

 Learn more:
  PowerShell in Depth: An Administrator's Guide (http://www.manning.com/jones6/)
  PowerShell Deep Dives (http://manning.com/hicks/)
  Learn PowerShell 3 in a Month of Lunches (http://manning.com/jones3/)
  Learn PowerShell Toolmaking in a Month of Lunches (http://manning.com/jones4/)
  
    ****************************************************************
    * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
    * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
    * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
    * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
    ****************************************************************
 
 .Example
 PS C:\> Get-MyService b* -status stopped -comp chi-dc04

Status   Name               DisplayName                           
------   ----               -----------                           
Stopped  BITS               Background Intelligent Transfer Ser...
 
 .Link
 Get-Service
 
 #>

[CmdletBinding(DefaultParameterSetName='Default', RemotingCapability='SupportedByCommand')]
 param(
     [Parameter(ParameterSetName='Default', Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
     [Alias('ServiceName')]
     [string[]]$Name, 
     [ValidateNotNullorEmpty()]
     [System.ServiceProcess.ServiceControllerStatus]$Status="Running",
     [Parameter(ValueFromPipelineByPropertyName=$true)]
     [Alias('Cn')]
     [ValidateNotNullOrEmpty()]
     [string[]]$ComputerName = $env:COMPUTERNAME, 
     [Alias('DS')]
     [switch]$DependentServices, 
     [Alias('SDO','ServicesDependedOn')]
     [switch]$RequiredServices, 
     [Parameter(ParameterSetName='DisplayName', Mandatory=$true)]
     [string[]]$DisplayName, 
     [ValidateNotNullOrEmpty()]
     [string[]]$Include, 
     [ValidateNotNullOrEmpty()]
     [string[]]$Exclude, 
     [Parameter(ParameterSetName='InputObject', ValueFromPipeline=$true)]
     [ValidateNotNullOrEmpty()]
     [System.ServiceProcess.ServiceController[]]$InputObject
  ) 
  
 begin {
 
     Write-Verbose -Message "Starting $($MyInvocation.Mycommand)"  

     Write-Verbose "Getting services with a status of $status on $($Computername.toUpper())"
 
     try {
         $outBuffer = $null
         if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
         {
             $PSBoundParameters['OutBuffer'] = 1
         }

         #remove Status parameter from bound parameters since Get-Service won't recognize it
         $PSBoundParameters.Remove("Status") | Out-Null

         $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Get-Service', [System.Management.Automation.CommandTypes]::Cmdlet)
         #$scriptCmd = {& $wrappedCmd @PSBoundParameters }
         #my modified command 
         $scriptCmd = {& $wrappedCmd @PSBoundParameters | Where-Object {$_.status -eq $Status } }
         $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
         $steppablePipeline.Begin($PSCmdlet)
     } catch {
         throw
     }
 } #begin
 
 process  {
     try {
         $steppablePipeline.Process($_)
     } catch {
         throw
     }
 } #process
 
 end {
     try {
         $steppablePipeline.End()
     } catch {
         throw
     }
     Write-Verbose -Message "Ending $($MyInvocation.Mycommand)" 
 } #end
  
} #end function Get-MyService

set-alias -Name gsv2 -Value Get-MyService

ใช่ ฉันสามารถเขียนฟังก์ชันของตัวเองที่เรียกว่า Get-Service ได้ แต่ฉันต้องเขียนโค้ดทั้งหมดเพื่อรองรับพารามิเตอร์ทั้งหมดสำหรับ Get-Service ด้วยคำสั่งพรอกซี สิ่งที่ฉันต้องทำคือใส่โค้ดของตัวเอง

#my modified command 
$scriptCmd = {& $wrappedCmd @PSBoundParameters | Where-Object {$_.status -eq $Status } }

กล่าวอีกนัยหนึ่ง ฉันปล่อยให้ Get-Service ทำหน้าที่ของมันแล้วกรองผลลัพธ์ ตอนนี้ฉันทำสิ่งนี้ได้อย่างง่ายดาย:

PS C:\Scripts> get-myservice w* -Status stopped -ComputerName chi-dc01

Status   Name               DisplayName                           
------   ----               -----------                           
Stopped  wbengine           Block Level Backup Engine Service     
Stopped  WbioSrvc           Windows Biometric Service             
Stopped  WcsPlugInService   Windows Color System                  
Stopped  WdiServiceHost     Diagnostic Service Host               
Stopped  WdiSystemHost      Diagnostic System Host                
Stopped  Wecsvc             Windows Event Collector               
Stopped  WinHttpAutoProx... WinHTTP Web Proxy Auto-Discovery Se...
Stopped  wmiApSrv           WMI Performance Adapter               
Stopped  wudfsvc            Windows Driver Foundation - User-mo...

หรือเพราะฉันพิมพ์ข้อความนี้ ฉันจึงใช้นามแฝงของตัวเองได้

สิ่งหนึ่งที่ฉันต้องการชี้ให้เห็นคือสำหรับคุณสมบัติสถานะใหม่ คุณจะสังเกตเห็นว่าฉันไม่ได้แปลงมันเป็นสตริง

[System.ServiceProcess.ServiceControllerStatus]$Status="Running"

ฉันสามารถทำให้มันเป็นสตริงได้ แต่โดยใช้การแจงนับจริง PowerShell จะเติมค่าที่เป็นไปได้ให้อัตโนมัติ

ฉันรู้ได้อย่างไรว่าควรใช้อะไร? ฉันใช้ Get Member

PS C:\Scripts> get-service bits | get-member status

   TypeName: System.ServiceProcess.ServiceController

Name   MemberType Definition                                                 
----   ---------- ----------                                                 
Status Property   System.ServiceProcess.ServiceControllerStatus Status {get;}

มันไม่ได้ยากหรือใช้เวลานานขนาดนั้นจริงๆ ฉันใช้เวลาเขียนโพสต์บนบล็อกนี้มากกว่าที่ฉันใช้เวลาสร้างฟังก์ชัน

ฉันหวังว่าสิ่งนี้จะเป็นแรงบันดาลใจให้คุณสร้างเครื่องมือ PowerShell ของคุณเอง และคุณจะได้แบ่งปันผลงานของคุณ

บทความที่เกี่ยวข้อง