我想检查系统中是否已存在用户帐户。
$SamAc = Read-Host 'What is your username?'
$User = Get-ADUser -Filter {sAMAccountName -eq "$SamAc"}
我不确定原因,但$User
将始终返回null,即使{sAMAccountName -eq "$SamAc"}
应该为真。
我在这里缺少什么?
编辑:
这是缺少的:
$User = Get-ADUser -Filter "sAMAccountName -eq '$SamAc'"
编者注: 脚本块({ ... }
)已替换为字符串。功能
答案 0 :(得分:33)
现有答案中有宝贵的信息,但我认为更有针对性的总结是有帮助的:
<强> TL;博士强>
绝不使用脚本块 - { ... }
- 来构建-Filter
- 参数参数 for 任何 cmdlet 。
Get-Help about_ActiveDirectory_Filter
)。 始终使用字符串 构建-Filter
- 参数参数,因为参数的实际类型是< / em> [string]
Get-ADUser -Filter "sAMAccountName -eq '$SamAc'"
Get-Help about_ActiveDirectory_Filter
您传递给-Filter
的任何参数无论如何都会被强制转换为字符串,之前将传递给Get-ADUser
cmdlet ,因为-Filter
参数的类型为[string]
- 跨支持此参数的所有 cmdlet;使用Get-ADUser -?
通常使用-Filter
, cmdlet 可以使用特定于域的语言来解释该字符串,该语言通常具有< em>与PowerShell 没什么共同之处。
Get-ADUser
,则Get-Help about_ActiveDirectory_Filter
使用 PowerShell 字符串插值(或文字和变量引用/表达式的字符串连接)到&#34; bake&#34;任何变量都将引用到字符串,预先 。
例如,以下命令全部工作且在功能上等效,使用各种 PowerShell 技术构造字符串,引用样式和转义字符的变化:
# All these commands are equivalent.
Get-ADUser -Filter "sAMAccountName -eq ""$SamAc"""
Get-ADUser -Filter "sAMAccountName -eq `"$SamAc`"" #`
Get-ADUser -Filter "sAMAccountName -eq '$SamAc'"
Get-ADUser -Filter ('sAMAccountName -eq "' + $SamAc + '"')
重要的一点是确保$SamAc
通过双引号字符串"..."
或显式字符串连接来预先扩展(由其值替换) (+ $SamAc + ...
)。
例如,如果$SamAc
包含jdoe
,则上述命令会将以下(等效)文字之一传递给-Filter
:
sAMAccountName -eq "jdoe"
sAMAccountName -eq 'jdoe'
但是,如果数据类型不是数字和字符串,您可能仍需要使用 AD提供商的变量评估 (见下文):
例如,AD提供商 [1] 不会将字符串化的[datetime]
值(例如08/15/2018 12:45:58
)识别为日期。
在那种情况下:
'...'
)$date
),而不是表达式($date.Year
或$($date.Year)
) ; e.g:# Note the use of '...' and be sure to use just a variable reference,
# not an expression.
# With this approach, never use embedded quoting, even with string variables.
Get-ADUser -Filter 'whenChanged -ge $date'
警告:此方法无法使用implicitly remoting modules,因为然后在远程计算机上评估变量引用。
脚本块在转换为字符串时,会在{
和}
- no 变量扩展(插值)之间生成文字内容)发生:
PS> {sAMAccountName -eq "$SamAc"}.ToString()
sAMAccountName -eq "$SamAc" # !! $SamAc was *not* expanded
因此,传递给sAMAccountName -eq "$SamAc"
的文字 Get-ADUser
。
Get-ADUser
,或许以支持脚本块语法/更像PowerShell,支持支持引用变量< em>未加引号 - 请注意"
周围缺少$SamAc
:
{ sAMAccountName -eq $SamAc } # as stated, Get-ADUser doesn't see the { and }
即Get-ADUser
对字符串 literal sAMAccountName -eq $SamAc
执行自己的Powershell- 之类的解释:就像你没有做过一样必须将"..."
中的变量引用括在PowerShell表达式中(例如'Windows_NT' -eq $env:OS
),您不必在此处 - 并且实际上必须不是,正如OP尝试失败所证明的那样。
但是,常规PowerShell脚本块的仿真不仅令人困惑 - 因为用户仍然认为他们需要附上引号 - 但半成品< / strong>,因此脆弱:
它不能与属性引用或方法调用一起使用:
{ sAMAccountName -eq $searchObj.SamAccountName } # !! DOES NOT WORK
它不能与implicitly remoting modules一起使用,因为在远程计算机上评估变量引用,在那里查找变量
while:
Get-Help about_ActiveDirectory_Filter
值得称赞的只是讨论字符串,
令人遗憾的是,Get-Help Get-ADUser
使用脚本块来表示其所有示例。
除了一个例外,示例在脚本块中仅使用 literals ,问题永远不会出现。 一个例外(截至本文撰写时)是:
-filter { lastLogon -le $logonDate }
这个例子恰好起作用 - 它使用了一个没有引号的简单变量引用 - 但是,由于选择了非字符串值,没有人会试图在中错误地应用封闭引号 case - 与比较 string 字段时不同。
脚本块语法诱人且方便,因为引用变得更容易:您不需要嵌套引用。
但是,由于所讨论的所有原因,应该避免使用。
[1]字符串扩展前端等效的AD-provider变量评估语句
Get-ADUser -Filter 'whenChanged -ge $date'
是
Get-ADUser -Filter "whenChanged -ge '$date'"
这意味着AD提供商最终会看到类似的东西
whenChanged -ge '01/15/2018 16:00:00'
作为过滤表达式;要使其工作,必须(a)接受字符串作为操作数,并且(b)了解PowerShell的日期/时间格式,即invariant culture& #39; s格式(类似美国的日期,首先列出月份,但是24小时制)
虽然我无法亲自测试此行为,但Luke报告AD提供商确实不识别此格式。
答案 1 :(得分:11)
当我第一次开始使用ActiveDirectory模块时,这就是我的一点,而且很难理解。
ActiveDirectory模块cmdlet的-Filter
参数实际上是在查找字符串。当您{sAMAccountName -eq "$SamAc"}
作为值时,它实际上正在寻找"sAMAccountName -eq ""`$SamAc"""
基本上,Powershell会解析参数并将其值转换为字符串,并且不会插入变量。尝试先建立字符串,它应该可以工作。
这样的事情:
$SamAc = Read-Host 'What is your username?'
$filter = "sAmAccountname -eq ""$SamAc"""
$User = Get-ADUser -Filter $filter
答案 2 :(得分:2)
我必须对此发表评论,因为它真的让我很难解决这个问题。
Joseph Alcorn有正确的想法。 filter参数接受一个字符串,然后对其进行求值以处理过滤器。让人们感到高兴的是,你可以选择使用大括号而不是{},如果你使用的是Where,它就不会像你期望的那样......它仍然必须像字符串一样对待。
$SamAc = Read-Host 'What is your username?'
$User = Get-ADUser -Filter "sAMAccountName -eq '$SamAc'"
我建议坚持使用引号使其对自己和他人更清晰/可读,并避免潜在的语法错误,或者坚持使用管道中的Where {}。这样做时,我发现最好在外面使用双引号和&amp;内部使用单引号,因此您仍然可以对变量进行intellisense检测。
答案 3 :(得分:0)
只需删除变量周围的引号:
$SamAc = Read-Host 'What is your username?'
$User = Get-ADUser -Filter {sAMAccountName -eq $SamAc}
这应该可以正常工作。
答案 4 :(得分:0)
if (($ADUser = Get-ADUser -filter "SamAccountName -eq '$(Read-Host Username)'") -ne $null) {$ADUser.SamAccountName} else {"Not Found"}
答案 5 :(得分:0)
如果有像我这样的人来到这里,仍然在扯头发,那是很少的附录:
-properties *
在查询中会很常见。不起作用,我敢肯定有人比我聪明
-属性mail,cn,wtf
etc确实按预期工作
答案 6 :(得分:-1)
好的,我让我最终使用以下语法并使用上面的示例:
此前:
$User = Get-ADUser -Filter "sAMAccountName -eq '$SamAc'"
工作版:
$user = Get-aduser -Filter "sAMAccountName -eq '$($SamAc)'"
在PowerShell访问变量字符串值之前,我必须在$ SamAc中添加$($)。
希望这对某人有帮助!