我想检查系统中是否已存在用户帐户。
1 2
| $SamAc = Read-Host 'What is your username?'
$User = Get-ADUser -Filter {sAMAccountName -eq"$SamAc"} |
我不确定为什么,但是即使{sAMAccountName -eq"$SamAc"}应该为true,$User仍将始终返回null。
我在这里想念什么?
编辑:
这是缺少的内容:
1
| $User = Get-ADUser -Filter"sAMAccountName -eq '$SamAc'" |
编者注:脚本块({ ... })已替换为字符串。
-
在变量周围丢失"。
-
类似的问题:stackoverflow.com/questions/16402194/
-
另一个类似的问题:stackoverflow.com/questions/12727388/
现有答案中包含有价值的信息,但是我认为更集中的摘要会有所帮助。请注意,此答案的原始形式提倡严格避免使用脚本块和AD提供程序变量评估,这些建议已被更细微的建议所取代。
好的。
tl; dr
好的。
1
| Get-ADUser -Filter 'sAMAccountName -eq $SamAc' |
不要引用变量引用( "$SamAc" del>)。
好的。
仅使用简单的变量引用(例如,$SamAc);不支持表达式(例如$SamAc.Name或$("admin_" + $SamAc));如有必要,请使用中间辅助变量;例如。:
好的。
$name ="admin_" + $SamAc; Get-ADUser -Filter 'sAMAccountName -eq $name'
好的。
通常,仅支持一部分PowerShell操作符,即使那些操作符也不总是以相同的方式运行-请参阅底部。
好的。
使用'...'引用整个-Filter参数。
好的。
使用脚本块({ ... })时,
Get-ADUser -Filter { sAMAccountName -eq $SamAc }从技术上讲也可行,从概念上讲是有问题的-请参阅底部。
好的。
好的。
注意:如果通过隐式远程处理模块使用Get-ADUser-无论是通过Import-PSSession自行创建,还是在PowerShell v7 +中通过Windows兼容性功能自行创建-'...'或{ ... }均不起作用,因为这样会引用变量在远程机器上求值,寻找那里的变量(徒劳);如果(Get-Command Get-ADUser).CommandType返回Function,则说明您使用的是隐式远程处理模块。
好的。
在那种情况下,您必须使用PowerShell的字符串内插("...")或从文字和变量引用/表达式的字符串连接,以将任何变量/表达式值"烘焙"到字符串中,预先:
Get-ADUser -Filter"sAMAccountName -eq `"$SamAc`""
请注意,对于字符串操作数,则必须使用嵌入式引号。
另外,请确保在"..."字符串内使用` -escape常量(例如$true,$false和$null),以便PowerShell不会在前面扩展它们。
注意:这项技术可能不适用于所有数据类型。至少[datetime]实例的默认字符串化(例如,AD提供程序无法识别01/15/2018 16:00:00;在这种情况下,将对实例的.ToFileTime()方法的调用结果嵌入到字符串中可能会有所帮助(未经测试) ;我不清楚是否还有其他数据类型需要类似的解决方法。
好的。
背景
传递给-Filter的任何参数在传递给Get-ADUser cmdlet之前,都将被强制转换为字符串,因为-Filter参数的类型为[string]-就像支持该参数的所有cmdlet一样。用Get-ADUser -?验证
好的。
通常,使用-Filter时,由cmdlet(底层PowerShell提供程序)使用特定于域的(查询)语言来解释该字符串,而该语言通常与PowerShell很少相同。
好的。
对于Get-ADUser,该特定于域的语言(查询语言)以Get-Help about_ActiveDirectory_Filter记录。
好的。
注意:在撰写本文时,此旧主题的更新版本不存在。这个GitHub问题要求一个。
好的。
使用Get-AdUser时,该语言无疑是在PowerShell上建模的,但是它具有许多局限性和一些行为差异,您必须意识到,尤其是:
好的。
仅支持PowerShell运算符的有限子集,其中一些表现出不同的行为;这是一个非详尽的清单:
好的。
-like / -notlike仅在通配符表达式中支持*(还不支持?和字符集/范围([...]))
'*'本身表示任何非空值(与PowerShell的通配符表达式不同,该值也匹配一个空值)。
*使用-notlike '*'代替-eq""或-eq $null来测试字段是否为空。
某些AD字段(例如DistinguishedName)仅单独支持'*',而不能作为较大模式的一部分;也就是说,它们仅支持空度测试。
好的。
不支持正则表达式匹配。
-lt / -le和-gt / -ge仅执行词汇比较。
引用不存在的/拼写错误的属性名称会使Get-AdUser命令悄悄地返回$null。
Enabled属性无法使用-eq $true进行测试-请参见此答案。
好的。
如上所述,仅支持简单的变量引用(例如$SamAc),不支持表达式(例如$SamAc.Name或$("admin_" + $SamAc))
好的。
好的。
好的。
尽管您可以使用脚本块({ ... })将变成字符串的内容传递给-Filter,并且此语法可以方便地嵌入引号,但由于两个原因,这是有问题的:
好的。
可能会误导您以为您正在传递一段PowerShell代码。值得注意的是,您可能很想使用不受支持的运算符和表达式,而不是简单的变量引用。
好的。
它创建了不必要的工作(尽管在实践中不太重要),因为您正在强制PowerShell首先将过滤器作为PowerShell代码解析为过滤器,仅在将参数绑定到-Filter时才将结果转换回字符串。
好的。
好的。
好的。
好。
当我第一次开始使用ActiveDirectory模块时,这一点让我很吃力,而弄清楚这一点却很痛苦。
ActiveDirectory模块cmdlet的-Filter参数实际上是在寻找字符串。当您将{sAMAccountName -eq"$SamAc"}作为值时,它实际上是在寻找"sAMAccountName -eq""`$SamAc"""
基本上,Powershell解析参数并将其值转换为字符串,并且不会对变量进行插值。尝试先构建字符串,它应该可以工作。
像这样:
1 2 3
| $SamAc = Read-Host 'What is your username?'
$filter ="sAmAccountname -eq""$SamAc"""
$User = Get-ADUser -Filter $filter |
-
这对我有很大的帮助,我终于使用了类似的命令:Get-ADObject -Properties mail, proxyAddresses -Filter"mail -eq""$Mail"" -or proxyAddresses -eq""smtp:$Mail"""
-
使用字符串而不是脚本块的好建议,但是Get-ADUser(令人惊讶地)确实解释了变量引用,只是在这种情况下它不希望包含文字引号。
我必须对此发表评论,因为它确实使我无法解决这个问题。
约瑟夫·奥尔康(Joseph Alcorn)有一个正确的想法。 filter参数采用字符串,然后对其进行求值以处理过滤器。令人们感到困扰的是,您可以选择使用大括号而不是{},如果您使用Where ...,这将无法正常工作,它仍然必须像字符串一样对待。
1 2
| $SamAc = Read-Host 'What is your username?'
$User = Get-ADUser -Filter"sAMAccountName -eq '$SamAc'" |
我建议使用引号使自己和他人更加清楚/可读,并避免潜在的语法错误,或者使用管道中的Where {}。这样做时,我发现最好在外部使用双引号,在内部使用单引号,这样您仍然可以对变量进行智能检测。
1
| if (($ADUser = Get-ADUser -filter"SamAccountName -eq '$(Read-Host Username)'") -ne $null) {$ADUser.SamAccountName} else {"Not Found"} |
-
您的答案比现有的答案如何? 您甚至没有为代码添加任何说明,以说明它为什么起作用(或为什么它比现有答案更好地起作用)。
-
尽管此代码段可以解决问题,但提供说明确实有助于提高您的帖子质量。 请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。
只需删除变量周围的引号即可:
$SamAc = Read-Host 'What is your username?'
$User = Get-ADUser -Filter {sAMAccountName -eq $SamAc}
这应该很好。
好的,我终于可以使用以下语法并从上方开始使用以下示例进行工作:
先前:
1
| $User = Get-ADUser -Filter"sAMAccountName -eq '$SamAc'" |
工作版本:
1
| $user = Get-aduser -Filter"sAMAccountName -eq '$($SamAc)'" |
在PowerShell可以访问变量字符串值之前,我必须向$ SamAc添加$($)。
-
这两个插值字符串("...")导致将完全相同的字符串文字传递给Get-ADUser,因此第一个字符串应与第二个字符串一样工作,您可以通过在PowerShell控制台窗口中运行以下命令来进行验证 :$SamAc = jdoe;"sAMAccountName -eq $SamAc";"sAMAccountName -eq $($SamAc)"。