2017-08-21 22 views
0

我有一個將停止並啓動服務的腳本。但是,我遇到了一些服務無法正常停止的問題,這需要用戶在服務器上進行干預。在運行腳本的啓動服務部分之前,我正在使用if語句來檢查列出的所有服務是否已停止,並且它們是否沒有腳本會彈出警報。在彈出窗口中列出服務和狀態

下面是執行此操作的腳本的片段。我試圖在彈出窗口中列出服務的狀態和啓動類型,但出於某種原因,我沒有收到列表返回。使用當前註釋掉的行,我得到返回的服務名稱,但它是一個字符串。

#$RunningServices = (Get-Service -ComputerName $targetServer | Where-Object {($_.Name -like '*serviceAgroup*'-or $_.Name -like '*serviceBgroup*') -and $_.Status -eq "Running"}) 
$RunningServices = (Get-Service -ComputerName $targetServer | 
        Where-Object {($_.Name -like '*serviceAgroup*' -or $_.Name -like '*serviceBgroup*') -and $_.Status -eq "Running"}) | 
        select DisplayName, Status, StartType | 
        sort DisplayName; 
Format-Table; 
$pop = New-Object -ComObject WScript.Shell 
$pop.Popup("Log onto $targetserver and stop Running serviceAgroup and serviceBgroup.`r`n$RunningServices", 0, "Services have not stopped!", 1) 
+1

這是我不明白你的問題是在這裏。什麼不起作用?你期望什麼行爲?你實際上得到了什麼樣的行爲? –

+0

絕對需要包含Status和StartType屬性嗎? – Persistent13

+0

目前彈出窗口有文字,但沒有列出服務的狀態和StartType @AnsgarWiechers – Mike

回答

1

管道的輸出分配給變量$RunningServices結束於sort DisplayName。輸出不會傳遞到Format-Table。如果將帶有對象(或對象數組)的變量放入字符串中,對象將展開爲它們各自的字符串表示形式。

示範:

 
PS C:\>$s = Get-Service | Select-Object -First 3 
PS C:\>$s 

Status Name    DisplayName 
------ ----    ----------- 
Stopped AeLookupSvc  Application Experience 
Stopped ALG    Application Layer Gateway Service 
Stopped AppIDSvc   Application Identity 

PS C:\>"$s" 
AeLookupSvc ALG AppIDSvc 
PS C:\> _ 

對服務的字符串表示是Name財產的價值,因爲你可以在上面看到。有了您的屬性選擇(無屬性Name)的結果應該是一個空字符串代替:

 
PS C:\>$s = Get-Service | Select-Object DisplayName,Status,StartType -First 3 
PS C:\>$s 

DisplayName        Status  StartType 
-----------        ------  --------- 
Application Experience     Stopped   Manual 
Application Layer Gateway Service  Stopped   Manual 
Application Identity     Stopped   Manual 

PS C:\>"$s" 

PS C:\> _ 

爲了得到表輸出作爲字符串必須通過管道不僅通過Format-Table,還可以通過Out-String你的對象名單。這是因爲Format-Table不會生成字符串輸出,而是格式對象的列表。 Out-String將這些轉換爲實際的字符串輸出。

 
PS C:\>$s1 = $s | Format-Table 
PS C:\>"$s1" 
Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShe 
ll.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Interna 
l.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEnt 
ryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.P 
owerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.In 
ternal.Format.FormatEndData 
PS C:\>$s2 = $s | Format-Table | Out-String 
PS C:\>"$s2" 

DisplayName        Status  StartType 
-----------        ------  --------- 
Application Experience     Stopped   Manual 
Application Layer Gateway Service  Stopped   Manual 
Application Identity     Stopped   Manual 

但即使如此,您的輸出可能不會是你所期望的。與PowerShell控制檯GUI對話框不同,它使用比例字體,這意味着並非所有字符都具有相同的寬度。因爲使用等寬字體時看起來像適當的表的東西在使用比例字體時很可能看起來相當變形。輸出上面的字符串的GUI對話是這樣的:

 
PS C:\>Add-Type -Assembly 'System.Windows.Forms' 
PS C:\>[Windows.Forms.Messagebox]::Show($s2) 

應當出示你是這樣的:

Service list (space-separated columns) in GUI dialog

要獲得至少稍微像樣的結果,我建議使用自定義格式字符串:

 
PS C:\>$s3 = $s | ForEach-Object {"{0}`t{1}`t{2}" -f $_.StartType,$_.Status,$_.DisplayName} | Out-String 
PS C:\>[Windows.Forms.Messagebox]::Show($s3) 

這應該產生一定程度上更像樣輸出:

Service list (tab-separated columns) in GUI dialog

上面利用這樣的事實,所述StartTypeStatus屬性的值不發生變化的長度太多,所以列可以通過用製表符分隔的值被對準相當良好的優勢。如果您必須在左側格式化服務名稱變得更加複雜,因爲您需要根據名稱中的字符數量和寬度插入可變數量的選項卡。我將把它作爲讀者的練習。


底線:更改您的代碼是這樣的:

Add-Type -Assembly 'System.Windows.Forms' 

$svc = Get-Service -ComputerName $targetServer | Where-Object { 
    ($_.Name -like '*serviceAgroup*' -or $_.Name -like '*serviceBgroup*') -and 
    $_.Status -eq 'Running' 
} | Select-Object DisplayName,Status,StartType 

$str = $svc | Sort-Object DisplayName | ForEach-Object { 
    "{0}`t{1}`t{2}" -f $_.StartType,$_.Status,$_.DisplayName 
} | Out-String 

[Windows.Forms.Messagebox]::Show($str) 

,它應該做你想做的(或多或少)。


附錄:顯示對象列表的屬性對用戶將是一個gridview一個更好的選擇:

$svc = Get-Service -ComputerName $targetServer | Where-Object { 
    ($_.Name -like '*serviceAgroup*' -or $_.Name -like '*serviceBgroup*') -and 
    $_.Status -eq 'Running' 
} | Select-Object DisplayName,Status,StartType 

$svc | Out-GridView -Title 'Services' 
+0

這是偉大的,正是我所需要的!感謝所有的幫助。 – Mike

0
$($RunningServices.DisplayName -join "`r`n")