简体   繁体   English

Powershell - 如果不工作(Windows 服务检查)

[英]Powershell - If is not working (windows services checks)

I am trying to build my own script to check some Windows services (status and start mode) and I am facing an issue on the IF... For example even if the service is "Running", it will never run the code inside the IF...我正在尝试构建自己的脚本来检查一些 Windows 服务(状态和启动模式),并且我在 IF 上遇到了问题......例如,即使服务是“正在运行”,它也永远不会运行里面的代码如果...

let me share my code below (I am a newbie on powershell so be gentle xD)让我在下面分享我的代码(我是 powershell 的新手,所以要温柔 xD)

For info, I will do more actions inside the IF and ELSE, it is just for the example.对于信息,我将在 IF 和 ELSE 中执行更多操作,这仅用于示例。

# import computers list, 1 by line
$Computers = get-content .\computers.txt

# define variable of services we want to check
$ServiceNetbios = "netbt"

# define variable to ask credentials
$Cred = Get-Credential

# declare Function to open a session a remote computer
Function EndPSS { Get-PSSession | Remove-PSSession }

EndPSS

########################################################
#                   BEGINNING OF SCRIPT                #
#                         by xxx                       #
#                       2022-02-03                     #
########################################################


# loop for each computer imported from the file
foreach ($computer in $computers) {
    
    # show name of computer in progress
    $computer

    # connect remotely to the computer
    $session = New-PSSession -ComputerName $computer -Credential $Cred

    # check Netbios service
    $StatusServiceNetbios = Invoke-Command -Session $session -ScriptBlock { Get-Service -Name $Using:ServiceNetbios | select -property * }
    
    # Check Netbios service started or not
    write-host $StatusServiceNetbios.Status
    
    if ($StatusServiceNetbios.Status -eq 'Running')
        {
           Write-host "IF Running"
        }
    else
    {
        write-host "IF NOT Running"
    }
    
EndPSS

}

and what return my script:什么返回我的脚本:

computername
Running           (<= the variable $StatusServiceNetbios.Status )
IF NOT Running    (<= the ELSE action)

Thanks you in advance for your help, this drive me crazy and maybe this is very simple...提前感谢您的帮助,这让我发疯,也许这很简单......

To complement Cpt.Whale's helpful answer , this is likely to be caused by the serialization and deserialization done by Invoke-Command :为了补充Cpt.Whale 的有用答案,这很可能是由Invoke-Command完成的序列化序列化引起的:

using namespace System.Management.Automation

$service = Get-Service netbt
$afterInvokeCmd = [PSSerializer]::Deserialize(([PSSerializer]::Serialize($service)))

$service.Status -eq 'Running'                   # => True
$afterInvokeCmd.Status -eq 'Running'            # => False
$afterInvokeCmd.Status.Value -eq 'Running'      # => True
$afterInvokeCmd.Status.ToString() -eq 'Running' # => True

To put some context to my answer, this is a nice quote from about_Remote_Output that can better explain why and what is happening:为了给我的回答加上一些背景,这是来自about_Remote_Output的一个很好的引用,可以更好地解释为什么以及发生了什么:

Because most live Microsoft .NET Framework objects (such as the objects that PowerShell cmdlets return) cannot be transmitted over the network, the live objects are "serialized".由于大多数实时 Microsoft .NET 框架对象(例如 PowerShell cmdlet 返回的对象)无法通过网络传输,因此实时对象被“序列化”。 In other words, the live objects are converted into XML representations of the object and its properties.换句话说,活动对象被转换为 object 及其属性的 XML 表示。 Then, the XML-based serialized object is transmitted across the network.然后,通过网络传输基于 XML 的序列化 object。

On the local computer, PowerShell receives the XML-based serialized object and "deserializes" it by converting the XML-based object into a standard .NET Framework object. On the local computer, PowerShell receives the XML-based serialized object and "deserializes" it by converting the XML-based object into a standard .NET Framework object.

However, the deserialized object is not a live object.但是,反序列化的 object 不是实时 object。 It is a snapshot of the object at the time that it was serialized, and it includes properties but no methods.它是 object 在序列化时的快照,它包含属性但没有方法。

This is probably because of the way powershell creates service objects - (Get-Service netbt).Status has a child property named Value :这可能是因为 powershell 创建服务对象的方式 - (Get-Service netbt).Status有一个名为Value的子属性:

$StatusServiceNetbios.Status

Value  
-----  
Running

# so Status is never -eq to 'Running':
$StatusServiceNetbios.Status -eq 'Running'
False

# use the Value property in your If statement instead:
$StatusServiceNetbios.Status.Value -eq 'Running'
True

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM