Powershell AD 语法 - If 语句复制字符串

Powershell AD Syntax - If Statement is duplicating a string

希望校对简单的新脚本编写器。

我制作了一个 Powershell Active Directory 脚本,用于根据我收到的每日 CSV 文件处理组织内请假 (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”不会回显到屏幕上。如果你把“三”改成“二”就可以了。