繁体   English   中英

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

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

我正在尝试构建自己的脚本来检查一些 Windows 服务(状态和启动模式),并且我在 IF 上遇到了问题......例如,即使服务是“正在运行”,它也永远不会运行里面的代码如果...

让我在下面分享我的代码(我是 powershell 的新手,所以要温柔 xD)

对于信息,我将在 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

}

什么返回我的脚本:

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

提前感谢您的帮助,这让我发疯,也许这很简单......

为了补充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

为了给我的回答加上一些背景,这是来自about_Remote_Output的一个很好的引用,可以更好地解释为什么以及发生了什么:

由于大多数实时 Microsoft .NET 框架对象(例如 PowerShell cmdlet 返回的对象)无法通过网络传输,因此实时对象被“序列化”。 换句话说,活动对象被转换为 object 及其属性的 XML 表示。 然后,通过网络传输基于 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.

但是,反序列化的 object 不是实时 object。 它是 object 在序列化时的快照,它包含属性但没有方法。

这可能是因为 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