Powershell AD 语法 - If 语句复制字符串
Powershell AD Syntax - If Statement is duplicating a string
希望校对简单的新脚本编写器。
我制作了一个 Powershell Active Directory 脚本,用于根据我收到的每日 CSV 文件处理组织内请假 (LOA) 的人员。
总而言之,我的问题部分应该:
- 如果该员工“休假”,请检查 $Line 变量的 currentStatus
- 禁用该 Active Directory 帐户。
- 获取该 AD 帐户的 'Description' 字段并 查找字符串部分“LOA - ”并仅在缺少时添加它。 问题是如果该字段描述中已经有“LOA - ”,它又放了一个……又一个,依此类推。
示例:
- 描述(良好):LOA - 厨师
- 描述(差):LOA - LOA - 厨师
- 描述(请否):LOA - LOA - LOA - 厨师
- 等等
我相当确定这里的这一行有问题,但我不知道如何解决它。
If ($null -ne ($newDescript | ? {$loaPhrases -notcontains $_}))
$loaPhrases = "LOA -|LOA-|LOA - |LOA- |LOA - LOA - "
ElseIf ($Line.currentStatus -eq "ON LEAVE")
{
#Add 'LOA - ' to description and disable AD
Set-ADUser $User.samAccountName -Enabled 0
'Disabled AD'
$Description = Get-ADUser $User.samAccountName -Properties Description | Select-Object -ExpandProperty Description
$newDescript = $Description.substring(0, $Description.IndexOf('-')+1)
If ($null -ne ($newDescript | ? {$loaPhrases -notcontains $_}))
{
$Description = "LOA - " + "$Description"
$Description = $Description.trim()
Set-ADUser $user.samAccountName -Description $Description
}
}
看起来你把它复杂化了一点。尝试使用 -match
语句来匹配您的 $loaPhrases.....
if ($description -notmatch $loaPhrases)
这可以通过更高级的编辑和检查来完成,但基本上是检查您的正则表达式字符串(用 | 分隔,就像您一样)是否有 loa 字符串。如果它不存在,它会添加“LOA - ”部分。
编辑: 添加选项以简单地查看字符串的开头
正如史蒂文在评论中指出的那样,您可能正在寻找描述开头的 LOA 字符串以确定是否需要添加一个。由于所有 LOA 字符串都以“LOA”开头,您可以简单地检查以确保它不是以“LOA”开头,以确定是否需要添加它。
if (!($description.startswith("LOA")))
!
翻转 $description.startswith("LOA")
返回的布尔值,所以如果它确实以“LOA”开头,它 returns false,如果它不是以“ LOA”,它 returns 为真,并进入 if
语句。
顺便说一句,早些时候,您设置了 -Enabled 0
。为了可读性,我的建议是将其更改为 -Enabled $false
,因为它清楚地表明您正在禁用该帐户,而不是将其设置为整数(即使这有效/ 0 通常是“假”)。
基于 ,考虑到您是新手,我想再补充几点。
考虑到您要更改超过 1 个 属性,您可以考虑使用不同的方法来设置用户对象。对于 Active Directory cmdlet,有一个我非常喜欢的实例化功能。这种方法可能如下所示:
ElseIf ($Line.currentStatus -eq "ON LEAVE")
{
# Get and store the instance in a variable:
$ADUser = Get-ADUser $User.samAccountName -Properties Description
$ADUser.Enabled = $false # Change the desired properties...
Write-Host 'Disabled AD'
If( $ADUser.Description -notmatch $loaPhrases )
{
$ADUser.Description = "LOA - " + $ADUser.Description.Trim()
}
# After changing properties run a single set command citing -Instance:
Set-ADUser -Instance $ADUser
}
注意,我使用了 Write-Host
而不是仅仅引用“禁用 AD”。在自上而下的脚本中,这可能没什么大不了的,但如果这段代码在一个函数中,该字符串将得到 returned。这会导致变体数组、意外函数 returns 和相关问题。同样,这里不一定是问题,但您会希望了解这一点。事实上,随着人们对 PowerShell 的掌握程度越来越高,这是一个常见的困惑。
我看到 -Instance
不喜欢空值的异常情况。但是,Description 属性似乎没有这个问题。 Splatting 可能是另一种选择,并且在比这稍微复杂的情况下非常有用......阅读更多关于 splatting here,
我还想多谈谈您的原始代码和后续示例。
首先 -contains
、-in
及其“非”变体在字符串上效果不佳。例如,"string" -contains "ing"
将 return “False”。因此,从概念上讲,该方法与您尝试做的事情不匹配。大多数人会使用 -match
,这是一种基于 RegEx 的方法。
注意:对于简单的东西 -Like
可以使用不太健壮的通配符方法。在您的情况下,-match
是您最好的选择,因为匹配字符串存在差异
-contains
和 -in
非常适合检查数组和其他集合:
$Array = "One", "Two"
$Array -contains "one"
"one" -in $Array
以上,-contains
和 -in
都将 return "True"
鉴于您想要搜索字符串开头的指示,我将修改 RegEx 以使用“^”锚点,例如:$loaPhrases = "^LOA -|^LOA-|^LOA - |^LOA- |^LOA - LOA - "
想想它是一个简单的 "^LOA"
可能会成功。
关于盖伊的回答,我会避免 .StartsWith()
或就此而言 .EndsWith()
只是因为它们区分大小写。
最后,我要指出与 $null
的比较是不必要的,即使除了其他问题。
$Array = "One", "Two"
If( ( $Array | Where-Object{ $_ -eq "Three"} ) ){
"Something"
}
在上面的示例中,“Something”不会回显到屏幕上。如果你把“三”改成“二”就可以了。
希望校对简单的新脚本编写器。
我制作了一个 Powershell Active Directory 脚本,用于根据我收到的每日 CSV 文件处理组织内请假 (LOA) 的人员。
总而言之,我的问题部分应该:
- 如果该员工“休假”,请检查 $Line 变量的 currentStatus
- 禁用该 Active Directory 帐户。
- 获取该 AD 帐户的 'Description' 字段并 查找字符串部分“LOA - ”并仅在缺少时添加它。 问题是如果该字段描述中已经有“LOA - ”,它又放了一个……又一个,依此类推。
示例:
- 描述(良好):LOA - 厨师
- 描述(差):LOA - LOA - 厨师
- 描述(请否):LOA - LOA - LOA - 厨师
- 等等
我相当确定这里的这一行有问题,但我不知道如何解决它。
If ($null -ne ($newDescript | ? {$loaPhrases -notcontains $_}))
$loaPhrases = "LOA -|LOA-|LOA - |LOA- |LOA - LOA - "
ElseIf ($Line.currentStatus -eq "ON LEAVE")
{
#Add 'LOA - ' to description and disable AD
Set-ADUser $User.samAccountName -Enabled 0
'Disabled AD'
$Description = Get-ADUser $User.samAccountName -Properties Description | Select-Object -ExpandProperty Description
$newDescript = $Description.substring(0, $Description.IndexOf('-')+1)
If ($null -ne ($newDescript | ? {$loaPhrases -notcontains $_}))
{
$Description = "LOA - " + "$Description"
$Description = $Description.trim()
Set-ADUser $user.samAccountName -Description $Description
}
}
看起来你把它复杂化了一点。尝试使用 -match
语句来匹配您的 $loaPhrases.....
if ($description -notmatch $loaPhrases)
这可以通过更高级的编辑和检查来完成,但基本上是检查您的正则表达式字符串(用 | 分隔,就像您一样)是否有 loa 字符串。如果它不存在,它会添加“LOA - ”部分。
编辑: 添加选项以简单地查看字符串的开头
正如史蒂文在评论中指出的那样,您可能正在寻找描述开头的 LOA 字符串以确定是否需要添加一个。由于所有 LOA 字符串都以“LOA”开头,您可以简单地检查以确保它不是以“LOA”开头,以确定是否需要添加它。
if (!($description.startswith("LOA")))
!
翻转 $description.startswith("LOA")
返回的布尔值,所以如果它确实以“LOA”开头,它 returns false,如果它不是以“ LOA”,它 returns 为真,并进入 if
语句。
顺便说一句,早些时候,您设置了 -Enabled 0
。为了可读性,我的建议是将其更改为 -Enabled $false
,因为它清楚地表明您正在禁用该帐户,而不是将其设置为整数(即使这有效/ 0 通常是“假”)。
基于
考虑到您要更改超过 1 个 属性,您可以考虑使用不同的方法来设置用户对象。对于 Active Directory cmdlet,有一个我非常喜欢的实例化功能。这种方法可能如下所示:
ElseIf ($Line.currentStatus -eq "ON LEAVE")
{
# Get and store the instance in a variable:
$ADUser = Get-ADUser $User.samAccountName -Properties Description
$ADUser.Enabled = $false # Change the desired properties...
Write-Host 'Disabled AD'
If( $ADUser.Description -notmatch $loaPhrases )
{
$ADUser.Description = "LOA - " + $ADUser.Description.Trim()
}
# After changing properties run a single set command citing -Instance:
Set-ADUser -Instance $ADUser
}
注意,我使用了 Write-Host
而不是仅仅引用“禁用 AD”。在自上而下的脚本中,这可能没什么大不了的,但如果这段代码在一个函数中,该字符串将得到 returned。这会导致变体数组、意外函数 returns 和相关问题。同样,这里不一定是问题,但您会希望了解这一点。事实上,随着人们对 PowerShell 的掌握程度越来越高,这是一个常见的困惑。
我看到 -Instance
不喜欢空值的异常情况。但是,Description 属性似乎没有这个问题。 Splatting 可能是另一种选择,并且在比这稍微复杂的情况下非常有用......阅读更多关于 splatting here,
我还想多谈谈您的原始代码和后续示例。
首先 -contains
、-in
及其“非”变体在字符串上效果不佳。例如,"string" -contains "ing"
将 return “False”。因此,从概念上讲,该方法与您尝试做的事情不匹配。大多数人会使用 -match
,这是一种基于 RegEx 的方法。
注意:对于简单的东西 -Like
可以使用不太健壮的通配符方法。在您的情况下,-match
是您最好的选择,因为匹配字符串存在差异
-contains
和 -in
非常适合检查数组和其他集合:
$Array = "One", "Two"
$Array -contains "one"
"one" -in $Array
以上,-contains
和 -in
都将 return "True"
鉴于您想要搜索字符串开头的指示,我将修改 RegEx 以使用“^”锚点,例如:$loaPhrases = "^LOA -|^LOA-|^LOA - |^LOA- |^LOA - LOA - "
想想它是一个简单的 "^LOA"
可能会成功。
关于盖伊的回答,我会避免 .StartsWith()
或就此而言 .EndsWith()
只是因为它们区分大小写。
最后,我要指出与 $null
的比较是不必要的,即使除了其他问题。
$Array = "One", "Two"
If( ( $Array | Where-Object{ $_ -eq "Three"} ) ){
"Something"
}
在上面的示例中,“Something”不会回显到屏幕上。如果你把“三”改成“二”就可以了。