Powershell(如果不存在)条件无法正常工作

Powershell(如果不存在)条件无法正常工作,powershell,if-statement,Powershell,If Statement,我正在努力满足两个条件,但似乎其中只有一个有效。我正在努力做到: 如果用户已连接且未处于锁定屏幕,请请求许可。命令本身已经过验证,并且可以单独工作,但我肯定遗漏了什么。以下是我所拥有的: if (Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem | Select-Object -expandproperty UserName -and -not (get-process -ComputerName $poste -nam

我正在努力满足两个条件,但似乎其中只有一个有效。我正在努力做到:

如果用户已连接且未处于锁定屏幕,请请求许可。命令本身已经过验证,并且可以单独工作,但我肯定遗漏了什么。以下是我所拥有的:

if (Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem | Select-Object -expandproperty UserName -and -not (get-process -ComputerName $poste -name logonui)) {

"ask for permission"

}
现在它只是不在这个代码中,它跳转到下面的部分,那里发生了其他事情

我的语法有什么问题

从我的CMD时代起,我就可以用这种老式的方式解决它:

Clear-Variable -name statut_user
$statut_user -eq 0
if (Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem | Select-Object -expandproperty UserName) {$statut_user +=1}
if (-not (get-process -ComputerName $poste -name logonui)) {$statut_user += 1}


if ($statut_user -eq 2)  { 
"ask for permission"
}
它可以工作,但在两种情况下不如一个合适的内衬干净。谢谢你的帮助

答案编辑:多亏了下面vonPryz的答案,我最终使用了:

$utilisateur = Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem | Select-Object -expandproperty UserName
$ecran_verr = get-process -ComputerName $poste -name logonui

if( -not ($ecran_verr) -and ($utilisateur)) { 

"ask for permission"

}

目标是清晰,而不是小的代码库大小。不要在 >如果语句中调用WMI调用,并对结果进行管道化,请考虑更可读的东西。这样,

$cs = gwmi -computername $p Win32_ComputerSystem
$uname = $cs | select-object -expandproperty UserName
$logonui = get-process -ComputerName $p -name logonui

if( -not ($logonui) -and ($uname )) { 
  # Stuff
}

这种方法可以很容易地检查WMI对象是否包含合理的值,不管这些值是什么。然后编写简洁的条件语句应该会更容易。

将表达式分解为多个步骤对于调试来说总是一个好主意,如中所示,有时您确实希望在没有辅助变量的情况下简化单个表达式

我的语法有什么问题

您缺少
(…)
关于
获取WmiObject…|选择对象…
pipeline

要将命令或管道用作更大表达式的一部分,必须始终将其括在
(…)
PowerShell中的命令是对可执行文件的调用,可以是cmdlet、函数、别名或外部程序

一个简单的例子:

# !! BROKEN: tokens `-eq 'jdoe'` are interpreted as *arguments for Select-Object*
# !! rather than as operator -eq and RHS 'jdoe'
if (Get-WmiObject Win32_ComputerSystem | Select-Object -Expand UserName -ne 'jdoe') {
  'not jdoe'
}

# OK: (...) around the pipeline properly embeds it in the overall expression:
if ((Get-WmiObject Win32_ComputerSystem | Select-Object -Expand UserName) -ne 'jdoe') {
  'not jdoe'
}
以下是原始命令的固定版本,该版本还改进了其他方面:

if (
  (Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem).UserName `
  -and -not `
  (Get-Process -ErrorAction SilentlyContinue -ComputerName $poste -name logonui)
) {
  "ask for permission"
}
  • 考虑到您的
    Get WmiObject
    调用仅输出一个对象,您可以直接访问
    .UserName
    属性,这也比管道连接到
    选择对象-ExpandProperty
    更有效

  • Get Process
    如果找不到具有给定名称的进程,则会输出一个非终止错误,因此
    -ErrorAction SilentlyContinue
    会抑制该错误

  • 请注意,
    `
    用作行连续字符,它允许将条件扩展到多行,使其更具可读性。
    请注意,
    `
    必须位于行的最末端


当我处理复杂的
if
语句时,我总是计算出简单的条件是什么,把它们括起来,然后用
-和
-或
连接起来,和/或用
-不
作为前缀。然后,也只有在那时,我才能用
if(…)
来包装它。你试过那种技巧吗?如果你这样做,你可能会发现自己的错误。好提示让我试试;)需要更多的时间吗如果((Get-WMIOObject–ComputerName$poste–Class Win32_ComputerSystem | Select Object–expandproperty UserName)-和(-not(Get-process–ComputerName$poste–name logonui))){仍然无法使用:$usiliateur=Get WmiObject–ComputerName$poste–Class Win32_ComputerSystem |选择对象-expandproperty用户名$ecran_verr=Get进程-ComputerName$poste-name logonui if(-not($ecran_verr)-和($usiliateur)){“请求许可”}“对于行延拓来说,这太好了,我会经常使用它!这让它更加清晰。@Rakha:是的,尽管它可能很棘手,因为它后面甚至不允许有空格(而且,它会抛出so的语法高亮显示)。请注意,有些情况下甚至不需要它,例如在
{
之后。