PowerShell: создание локального пользователя

Недавно ко мне обратились с вопросом о странном поведении достаточно простой функции. Она создаёт локального пользователя с заданным именем и паролем, и должна возвращать в качестве результата объект с двумя свойствами: UserName и Password (Ну на самом деле функция была чуть сложнее, но нам интересна только эта часть ).

Вот её код:

Теперь попробуем создать пользователя с помощью этой функции:
PS C:\Windows\system32> $Result = createUser -name Tester -pass P@ssw0rd
PS C:\Windows\system32> $Result
Username Password
-------- --------
Tester P@ssw0rd

PS C:\Windows\system32> $Result.UserName
PS C:\Windows\system32> $Result.Password
PS C:\Windows\system32>
Странно? Если просто вызываем переменную, то видно 2 свойства: UserName, Password, и их значения. Однако при попытке просто получить значения этих свойств мы получаем… ничего. В чём же дело?
PS C:\Windows\system32> $Result.gettype().name
Object[]
PS C:\Windows\system32> $Result.count
3

Квадратные скобки в конце типа объекта, говорят о том что это не просто объект, а массив. Причем как говорит его свойство .Count – из трех элементов. Зная это можно обратиться к свойствам:
PS C:\Windows\system32> $Result[2].Username
Tester
PS C:\Windows\system32> $Result[2].Password
P@ssw0rd

Нужный нам элемент будет лишь третьим по счёту (массивы индексируются с 0). Что касается первых двух элементов:
PS C:\Windows\system32> $Result[0].gettype().name
You cannot call a method on a null-valued expression.
At line:1 char:19
+ $Result[0].gettype <<< $Result[0] -eq $null
True

Их просто не существует, точнее они равны $null, пустоте. А взялись они благодаря вызовам методов ADSI SetPassword() и SetInfo(). Уж не знаю зачем, но видимо авторы данных методов посчитали это прикольным А в PowerShell есть одна тонкость: все данные которые не присваиваются переменной, не передаются по конвейеру, и не обрабатываются другим способом – отправляются на вывод. То есть функция function test {Get-process powershell; "Test"; del c:\test.txt; return 2+1; 2} вернёт вам массив состоящий из объекта процесса, строки Test и числа 3. Двойка в конце не вернётся лишь потому что return предотвращает дальнейший вывод данных (возвращает не единственный результат, а лишь последний из ряда).
Короче говоря в нашей ситуации $null’ы возвращённые методами, присоеденились к результату возвращаемому функцией, и всё испортили Чтобы этого не произошло, можно избавиться от этих $null’ов, например… отправив их в Null
$user.SetPassword($Password) | Out-Null
$user.SetInfo() | Out-Null

источник