在弹出窗口中列出服务和状态 [英] Listing services and status in a pop-up

查看:79
本文介绍了在弹出窗口中列出服务和状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本,它将停止和启动服务.但是,我遇到了一些服务无法正确停止的问题,这需要用户在服务器上进行干预.在脚本的启动服务部分运行之前,我使用if语句检查列出的所有服务是否都已停止,如果没有,脚本将弹出警报.

I have a script that will stop and start services. However, I've had a few issues where services aren't stopping correctly which requires user intervention on the server. Before the start services portion of the script runs I'm using an if statement to check if all the services listed have stopped and if they haven't the script will pop an alert.

下面是执行此操作的脚本的摘要.我试图在弹出窗口中列出服务的状态和启动类型,但是由于某种原因,我没有得到列表返回.使用当前被注释掉的行,我得到了返回的服务名称,但是它是一个字符串.

Below is a snippet of the script that does this. I'm trying to list the services in the pop-up with their status and start-up type but for some reason I'm not getting the list return. Using the line that is currently commented out I'm getting the service names returned but it's in a string.

#$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)

推荐答案

您为其分配给变量$RunningServices的输出的管道在sort DisplayName处结束.输出不会传递到Format-Table.如果将带有对象(或对象数组)的变量放入字符串中,则对象将展开为各自的字符串表示形式.

The pipeline whose output you assign to the variable $RunningServices ends at sort DisplayName. The output is not passed into Format-Table. If you put a variable with an object (or an array of objects) into a string, the objects are expanded to their respective string representation.

演示:


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)后,结果应为空字符串:

For services the string representation is the value of the Name property, as you can see above. With your property selection (without the property Name) the result should be an empty string instead:


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将它们转换为实际的字符串输出.

To get the table output as a string you must pipe your object list not only through Format-Table, but also through Out-String. That's because Format-Table doesn't generate string output, but a list of format objects. Out-String converts these into actual string output.


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对话框中输出上述字符串:

But even with that your output probably won't be what you expect. Unlike the PowerShell console GUI dialogs use a proportional font, meaning that not all characters have the same width. Because of that something that looks like a proper table when using a monospace font will most likely look rather deformed when using a proportional font. Outputting the above string in a GUI dialog like this:


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

应该向您显示以下内容:

should present you with something like this:

要获得至少某种程度可呈现的结果,我建议使用自定义格式字符串:

To get an at least somewhat presentable result I'd suggest using custom format strings:


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

这应该产生更具表现力的输出:

That should produce somewhat more presentable output:

以上内容利用了StartTypeStatus属性的值的长度变化不大的事实,因此可以通过使用制表符分隔值来合理地对齐列.如果必须在左侧保留服务名称,则格式会变得更加复杂,因为您需要根据名称中字符的数量和宽度插入不同数量的制表符.我将把它留给读者作为练习.

The above takes advantage of the fact that the values of the StartType and Status properties don't vary too much in length, so the columns can be aligned reasonably well by separating the values with tab characters. If you must have the service names on the left side formatting becomes a lot more complicated, because you need to insert a variable amount of tabs depending on the number and width of the characters in the names. I'm going to leave that as an exercise for the reader.

底线:将您的代码更改为以下内容:

Bottom line: Change your code to something like this:

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)

它应该(或多或少)执行您想要的操作.

and it should do (more or less) what you want.

附录:向用户显示对象列表属性的更好选择是

Addendum: A better option for displaying the properties of a list of objects to the user would be a 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'

这篇关于在弹出窗口中列出服务和状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆