需要添加一个步骤以获得意外结果

时间:2019-05-17 18:59:45

标签: powershell scripting active-directory ps1

我有一个运行的脚本,该脚本告诉我用户是否属于特定的AD组,该组将标识他正在使用的VPN。当脚本遇到不属于域的用户时,它会中断并且不会再走了,我想寻求帮助,以添加一段可以打印出该用户不在系统输出文件中的用户,并且继续检查其余部分。

此外,当我仅对我知道的用户在系统中运行它时,会将其名称与不属于该用户的AD组多次放置。

Get-Content D:\Scripts\VPNGroup\List1.txt | Foreach-Object {
   $name =  ( ( net user $_ /domain | select-string 'full name' | out-string ).Trim() -split "`r`n" ) |
      Foreach-Object { $_.Substring(29).Trim() -split 'full name' } |
      Where-Object { -Not [String]::IsNullOrWhiteSpace($_) } 
      $group =  ( ( net user $_ /domain | select-string '\*' | out-string ).Trim() -split "`r`n" ) |
      Foreach-Object { $_.Substring(29).Trim() -split '\*' } |
      Where-Object { -Not [String]::IsNullOrWhiteSpace($_) } 
      $group >> D:\Scripts\VPNGroup\FullList.txt


   $ADgroups = Get-Content D:\Scripts\VPNGroup\FullList.txt

   $VPNgroups = foreach($line in $ADgroups) {
       if ($line -like "VPN-GRP*") {$name + $line >> D:\Scripts\VPNGroup\ADGroups.txt}

   }
}

这是用户不在系统中时得到的输出:

net : The user name could not be found.
At line:2 char:17
+    $name =  ( ( net user $_ /domain | select-string 'full name' | out-string ).T ...
+                 ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (The user name could not be found.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

More help is available by typing NET HELPMSG 2221.
Exception calling "Substring" with "1" argument(s): "startIndex cannot be larger than length of string.
Parameter name: startIndex"
At line:3 char:24
+       Foreach-Object { $_.Substring(29).Trim() -split 'full name' } |
+                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

当它们在系统中时,我会用错误的IE提示他们:

Michael Smith VPN-GRP-1
迈克尔·史密斯VPN-GRP-1
迈克尔·史密斯VPN-GRP-1
迈克尔·史密斯VPN-GRP-1
迈克尔·史密斯VPN-GRP-1
迈克尔·史密斯VPN-GRP-2
迈克尔·史密斯VPN-GRP-2
迈克尔·史密斯VPN-GRP-2
迈克尔·史密斯VPN-GRP-2
迈克尔·史密斯VPN-GRP-2
迈克尔·史密斯VPN-GRP-3
迈克尔·史密斯VPN-GRP-3
迈克尔·史密斯VPN-GRP-3
贾斯汀·琼斯VPN-GRP-1
贾斯汀·琼斯VPN-GRP-1
贾斯汀·琼斯VPN-GRP-1
贾斯汀·琼斯VPN-GRP-1
贾斯汀·琼斯VPN-GRP-2
贾斯汀·琼斯VPN-GRP-2
贾斯汀·琼斯(Justin Jones)VPN-GRP-3
贾斯汀·琼斯(Justin Jones)VPN-GRP-3
贾斯汀·琼斯(Justin Jones)VPN-GRP-3
贾斯汀·琼斯(Justin Jones)VPN-GRP-3
贾斯汀·琼斯VPN-GRP-4
......继续为超过1k用户提供服务
每个用户只是这些广告组之一的成员。

2 个答案:

答案 0 :(得分:1)

这里的问题是,对于每个单个用户,您要将其组附加到FullList.txt。因此,对于每个人,您还需要对照每个先前的人的组进行检查。

我要进行的第一个调整是将净用户的输出存储到一个变量中,这样就不必使用$Query = cmd /c net user 'asdf' /domain 2> &1来多次运行它。

接下来,我们将检查它是否在if语句中找到有效用户:

if ( $Query | Select-String 'The user name could not be found.') {
    "$_ is not a valid user" | Out-File -FilePath D:\Scripts\VPNGroup\ADGroups.txt -Append
  }

否则,如果它是有效用户,那么我们可以继续执行脚本的其余部分并提取名称和组。我自由地简化了一些代码,并使用正则表达式来获取名称。

$Query | Where-Object { $_ -match 'Full\sName\s+(\w+\s\w+)' } 
    $name = $Matches[1]

    $groups = $Query | select-string '\*' | Out-String |
    ForEach-Object { $_.Substring(29).Trim() -split '\*' -split "`r`n" } |
    Where-Object { -Not [String]::IsNullOrWhiteSpace($_) }

我删除了将其输出到文件的步骤,该步骤然后由脚本再次读取,这似乎是多余的。但是最后,我们检查是否其中一个组与VPN字符串匹配:

foreach ($group in $groups) {
    if ($group -like 'VPN-GRP*') { $name + $group | Out-File 'D:\Scripts\VPNGroup\ADGroups.txt' -Append }

那应该做到。让我知道我是否搞砸了,或者仍然无法正常工作。这就是它们的全部外观:

Get-Content D:\Scripts\VPNGroup\List1.txt | Foreach-Object {
  $Query = cmd /c net user $_ /domain 2`>`&1
  if ( $Query | Select-String 'The user name could not be found.') {
    "$_ is not a valid user" | Out-File -FilePath D:\Scripts\VPNGroup\ADGroups.txt -Append
  }
  else {
    $Query | Where-Object { $_ -match 'Full\sName\s+(\w+\s\w+)' } 
    $name = $Matches[1]

    $groups = $Query | select-string '\*' | Out-String |
    ForEach-Object { $_.Substring(29).Trim() -split '\*' -split "`r`n" } |
    Where-Object { -Not [String]::IsNullOrWhiteSpace($_) }

    foreach ($group in $groups) {
      if ($group -like 'VPN-GRP*') { $name + $group | Out-File 'D:\Scripts\VPNGroup\ADGroups.txt' -Append }
    }
  }
}

答案 1 :(得分:0)

如果是我,我将对域控制器进行ADSI搜索。不需要AD cmdlet。

$Groups = 'VPN-GRP-1','VPN-GRP-2','VPN-GRP-3','VPN-GRP-4'
$GroupHT = @{}
$LDAP = "DC=domain,DC=com"

ForEach($Group in $Groups){
    $Filter = "(&(sAMAccountName=$Group)(objectClass=group))"
    $Searcher = [adsisearcher]$Filter
    $Searcher.SearchRoot = "LDAP://$LDAP"
    $Searcher.PropertiesToLoad.Add('Member')|Out-Null
    $Results=$Searcher.FindAll()
    $Members=ForEach($User in $Results.Properties.Item('member')){
        $LDAP = $User -replace '^.+?,(?=DC=)'
        $Filter = "(&(DistinguishedName=$User)(objectClass=user))"
        $Searcher = [adsisearcher]$Filter
        $Searcher.SearchRoot = "LDAP://$LDAP"
        $Searcher.PropertiesToLoad.Add('SamAccountName')|Out-Null
        $UserResults=$Searcher.FindAll()
        $objProps=@{SamAccountName=$UserResults.Properties.Item('SamAccountName');FullName=$User -replace "CN=(.+?),.*",'$1'}
        New-Object PSObject -Property $objProps
    }
    $GroupHT.Add($Group,$Members)
}

$Results=ForEach($User in (Get-Content D:\Scripts\VPNGroup\List1.txt)){
    $UserInfo = $GroupHT.GetEnumerator()|?{$User -in $_.Value.SamAccountName}|%{"{0} {1}" -f ($_.Value|?{$_.SamAccountName -eq $User).FullName,$_.Key}
    If(![string]::IsNullOrWhitespace($UserInfo)){$UserInfo}Else{Write-Warning "User not found in a group: $user"}
}
$Results | Add-Content 'D:\Scripts\VPNGroup\ADGroups.txt'

这将为您提供一个以组名作为键的哈希表,以及一个具有每个组成员的FullName和SamAccountName的对象数组。然后,它遍历用户,引用哈希表以查找其组,如果未找到该组,则向屏幕输出警告。最后,它将所有找到的用户添加到文件中。