Я пытаюсь создать свой собственный скрипт для проверки некоторых служб 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)
Заранее спасибо за вашу помощь, это сводит меня с ума и, может быть, это очень просто...
2 ответа
Вероятно, это связано с тем, как 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
Чтобы дополнить полезный ответ Cpt.Whale, это, вероятно, вызвано сериализацией и десериализацией, выполненной Invoke-Command
:
using namespace System.Management.Automation
$service = Get-Service netbt
$service.Status -eq 'Running' # True
$afterInvokeCmd = [PSSerializer]::Deserialize(([PSSerializer]::Serialize($service)))
$afterInvokeCmd.Status -eq 'Running' # False
$afterInvokeCmd.Status.Value -eq 'Running' # True
ИЗМЕНИТЬ
Чтобы придать контекст моему ответу, это хорошая цитата из about_Remote_Output, которые могут лучше объяснить, почему и что происходит:
Поскольку большинство активных объектов Microsoft .NET Framework (например, объекты, возвращаемые командлетами PowerShell) не могут быть переданы по сети, активные объекты "сериализуются". Другими словами, живые объекты преобразуются в XML-представления объекта и его свойств. Затем сериализованный объект на основе XML передается по сети.
На локальном компьютере PowerShell получает сериализованный объект на основе XML и "десериализует" его, преобразуя объект на основе XML в стандартный объект .NET Framework.
Однако десериализованный объект не является живым объектом. Это моментальный снимок объекта на момент его сериализации, включающий свойства, но не методы.
Invoke-Command
переносит объект из удаленного сеанса в ваш локальный сеанс, он выполняет процесс сериализации объекта(ов), а затем десериализации это/они (это то, что делает PSSerializer
)
Похожие вопросы
Новые вопросы
windows
Написание программного обеспечения, специфичного для операционной системы Microsoft Windows: API-интерфейсы, поведение и т. Д. ОБЩАЯ ПОДДЕРЖКА WINDOWS НЕВОЗМОЖНА. Вопросы поддержки можно задать на https://superuser.com
"IF Running"
? Помимо того, что на самом деле не требуетсяInvoke-Command
, посколькуGet-Service
поддерживает удаленные компьютеры, я не понимаю, почему это не сработает.else
?(Get-Service -Name $Using:ServiceNetbios).Status
изInvoke-Command
, а затем условиеif($StatusServiceNetbios -eq 'Running')