Нужно добавить шаг для неожиданных результатов - PullRequest
0 голосов
/ 17 мая 2019

У меня есть скрипт, который запускает и сообщает мне, принадлежит ли пользователь к определенной группе 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
Джастин Джонс VPN-GRP-3
Джастин Джонс VPN-GRP-3
Джастин Джонс VPN-GRP-3
Джастин Джонс VPN-GRP-3
Джастин Джонс VPN-GRP-4
...... продолжается более 1 000 пользователей
Каждый пользователь является членом только одной из этих групп AD.

Ответы [ 2 ]

1 голос
/ 18 мая 2019

Проблема здесь в том, что для каждого отдельного пользователя вы добавляете его группы в FullList.txt.Таким образом, с каждым человеком, которого вы проверяете, также и против групп всех предыдущих людей.

Первая настройка, которую я сделаю, - это сохранить выходные данные net user в переменную, чтобы вам не пришлось ее запускатьнесколько раз, используя $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 }
    }
  }
}
0 голосов
/ 18 мая 2019

Если бы это был я, я бы выполнил поиск ADSI по контроллеру домена. Нет необходимости в командлетах AD.

$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'

В результате у вас останется хеш-таблица с именами групп в качестве ключей, а также массив объектов с полными именами и именами SamAccountName каждого члена группы. Затем он просматривает пользователей, обращается к хеш-таблице, чтобы найти их группу, и, если она не найдена, выдает предупреждение на экран. В конце он добавляет всех найденных пользователей в файл.

...