По профессии я системный администратор Linux, но мне нужно немного потрудиться. Моя проблема в следующем:
Я получаю список активных пользователей из AD с помощью этой команды:
$allusers= get-aduser -Filter {Enabled -eq $true} | FT samAccountName
Я хотел, чтобы $ allusers превратился в массив, заполненный строками вывода команды get-aduser. появление этого блока сразу после заполнения массива, похоже, подтверждает, что это действительно так.
for ($i; $i -le $allusers.length; $i++) {
$allusers[$i]
}
Большой! Итак, теперь я хочу проверить, существует ли данное имя пользователя в этом массиве. Я вижу, что в массивах есть очень удобная функция Contains (), которая, похоже, должна служить моей цели.
echo $allusers.Contains("joeq")
Но увы! Я получаю такую ошибку:
Method invocation failed because [System.Object[]] doesn't contain a method named 'contains'.
В C: \ Users \ dylanh \ jirauserpurge.ps1: 33 символа: 24 + echo $ allusers.contains <<<< ("joeq") + CategoryInfo: InvalidOperation: (содержит: String) [], RuntimeException + FullyQualifiedErrorId: MethodNotFound
Хммм ... Ладно, давай "старая школа"
for ($i; $i -le $allusers.length; $i++) {
if ($allusers[$i] -eq "joeq") {
echo "joeq present"
}
}
Условие никогда не выполняется! Мой мозг болит! Хорошо, возможно, здесь есть какие-то пробельные символы, вызывающие неприятности, давайте обрезать:
for ($i; $i -le $allusers.length; $i++) {
if ($allusers[$i].Trim() -eq "joeq") {
echo "joeq present"
}
}
Но нет, это приводит к следующему:
Method invocation failed because [Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData] doesn't contain a method named 'Trim'.
At C:\Users\dylanh\jirauserpurge.ps1:39 char:24
+ if ($allusers[$i].Trim <<<< () -eq "nickf") {
+ CategoryInfo : InvalidOperation: (Trim:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Ясно, что это какая-то проблема с приведением типов, которую мне не хватает. Что мне нужно сделать, чтобы разрешить поиск в «массиве» определенного значения?
ОБНОВЛЕНИЕ: с помощью ответа fdibot и комментария HopelessN00b у меня есть рабочее решение:
$allusers= get-aduser -Filter {Enabled -eq $true}
$usernames = @()
for ($i=0; $i -le $allusers.length; $i++) {
$usernames += $allusers[$i].SamAccountName
}
$usernames -contains "joeq"
Дополнительный цикл for кажется немного избыточным TBH (по крайней мере, он был бы в bash!) Ну что ж! спасибо за ваш вклад всем.
Проблема связана с вашей форматной таблицей :)
$allusers= get-aduser -Filter {Enabled -eq $true} | FT samAccountName
$allusers | gm
Имя типа: Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
Имя MemberType Определение ---- ---------- ---------- Equals Method bool Equals (System.Object obj) GetHashCode
Метод int GetHashCode () GetType
Тип метода GetType () ToString
Строка метода ToString () autosizeInfo
Свойство Microsoft.PowerShell.Commands.Internal.Format.AutosizeInfo, Syste ... ClassId2e4f51ef21dd47e99d3c952918aff9cd Строка свойства ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;} groupingEntry
Свойство
Microsoft.PowerShell.Commands.Internal.Format.GroupingEntry, Syst ... Свойство pageFooterEntry
Microsoft.PowerShell.Commands.Internal.Format.PageFooterEntry, Sy ... Свойство pageHeaderEntry
Microsoft.PowerShell.Commands.Internal.Format.PageHeaderEntry, Sy ... Свойство shapeInfo
Microsoft.PowerShell.Commands.Internal.Format.ShapeInfo, System.M ...
Это не то, что вы хотите искать по имени пользователя.
Если ты сделаешь это
$allusers= get-aduser -Filter {Enabled -eq $true}
$allusers | gm
Вы получите коллекцию объектов со всеми вашими свойствами. И здесь вы можете проверить, если так
$allusers.SamAccountName -eq "joeq"
Теперь вы можете продолжить сценарий и зациклить список всех пользователей, попробуйте следующее:
get-aduser -Filter {Enabled -eq $true} | Foreach {
if ($_.SamAccountName -eq "something") { "OK" }
}
Вы можете использовать "select -expand xxx" для создания плоского (?) Массива, в котором вам не нужно использовать имя свойства для анализа массива.
$allusers = get-aduser -Filter {Enabled -eq $true} | select -expand samAccountName
PS C:\> $allusers.contains("GeoSword")
True
Если вам не нужно использовать $allusers
как набор пользовательских объектов несколько раз (или, если все, что вам нужно, это имена пользователей), вы можете сократить объем того, что храните в памяти оболочки, сделав следующее:
$usernames = (get-aduser -Filter {Enabled -eq $true}).samAccountName
$usernames.Contains("check_value")
Или скажите, что у вас есть целый массив проверочных значений, которые вы хотите перебрать с именем $check_array
и вы хотели проверить каждое имя пользователя, чтобы узнать, находятся ли они в этом массиве:
$usernames = (get-aduser -Filter {Enabled -eq $true}).samAccountName
foreach ($i in $check_array) {
$usernames.Contains($i)
}
Хотя, в зависимости от относительной длины двух массивов, второй может быть лучше:
foreach ($j in (get-aduser -Filter {Enabled -eq $true}).samAccountName) {
$check_array.Contains($j)
}
Наконец, если вам не нужно повторно использовать список имен пользователей после этого шага, и вам нужно только проверить его на одно значение проверки:
((get-aduser -Filter {Enabled -eq $true}).samAccountName).Contains("check_value")
Вернет логический результат этой проверки.
Однако этот последний метод не совсем оптимален, если вы пишете сценарий или функцию, которые кому-то другому может понадобиться разобрать, чтобы исправить или перепрофилировать в ваше отсутствие. Если это только для вас, и все, что вам нужно, это один логический результат, я бы пошел с ним, он должен работать примерно столько же времени, и вы не будете держаться за этот (потенциально) огромный массив имен пользователей (или даже больший массив объектов И массив имен пользователей). Опять же, если вы повторно используете этот массив пользовательских объектов, ваш путь должен быть в порядке.
Подсчет через массив с ($i=0; $i ...
, могло бы быть намного проще - PowerShell довольно хорошо выполняет итерацию с foreach
, но часто и вам это не нужно. Ваш последний код:
$allusers= get-aduser -Filter {Enabled -eq $true}
$usernames = @()
for ($i=0; $i -le $allusers.length; $i++) {
$usernames += $allusers[$i].SamAccountName
}
$usernames -contains "joeq"
может быть:
$usernames = Get-ADUser -Filter {Enabled -eq $true} | select -Expand sAmAccountName
$usernames -contains "joeq"
Если при выборе выбирается свойство или свойства для сохранения, а параметр раскрытия сводит это свойство к простой строке вместо того, чтобы сохранять его как пару имя / значение.
[Это соответствует тому же ответу, что и Craig620, но я отвечаю против цикла подсчета, поэтому путь к ответу другой].