Я создаю (локального) пользователя для запуска службы Windows. У меня есть веские причины не использовать СЕТЕВОЙ СЕРВИС, ЛОКАЛЬНЫЙ СЕРВИС или ЛОКАЛЬНУЮ СИСТЕМУ.
Я создаю пользователя через net user foobar "Abcd123!" /add
- это нормально работает.
С этой точки зрения, c:\users\foobar
не существует.
Если я создать домашний каталог пользователя, прежде чем пользователь либо войдет в систему (или, что более уместно), либо служба, для которой он предназначен, запустится, Windows создает профиль пользователя по соседству, называемый c:\users\foobar-{gibberish/SID/whatever}
- это непредсказуемое имя.
Мне нужно, чтобы в домашнем каталоге пользователя содержались такие вещи, как .ssh
каталог, .gitconfig
- подобные инструменты (не ограничиваясь этими инструментами), которые предполагают, что их будет использовать человек, и поэтому пользовательская конфигурация идет внутрь ~/...
. Обычно инструменты из наследия Unix.
Итак, существует ли программный (предпочтительно, PowerShell или готовая к использованию командная строка) способ сообщить Windows о необходимости создания профиля для локального пользователя?
Вещи, которые мне еще предстоит попробовать:
C:\users\default
(эквивалент /etc/skel
), потому что существует несколько разных пользователей услуг и один размер не подойдет всем. Это также не влияет на то, когда создается профиль пользователя, а только на то, что будет в нем, когда оно будет.Windows может создавать профиль пользователя по запросу, используя Создать профиль API
Однако, если вы не хотите создавать исполняемый файл для выполнения этой операции, вы можете вызвать API в PowerShell. Другие уже сделали это: пример на github.
Соответствующая часть кода:
$methodName = 'UserEnvCP'
$script:nativeMethods = @();
Register-NativeMethod "userenv.dll" "int CreateProfile([MarshalAs(UnmanagedType.LPWStr)] string pszUserSid,`
[MarshalAs(UnmanagedType.LPWStr)] string pszUserName,`
[Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszProfilePath, uint cchProfilePath)";
Add-NativeMethods -typeName $MethodName;
$localUser = New-Object System.Security.Principal.NTAccount("$UserName");
$userSID = $localUser.Translate([System.Security.Principal.SecurityIdentifier]);
$sb = new-object System.Text.StringBuilder(260);
$pathLen = $sb.Capacity;
Write-Verbose "Creating user profile for $Username";
try
{
[UserEnvCP]::CreateProfile($userSID.Value, $Username, $sb, $pathLen) | Out-Null;
}
catch
{
Write-Error $_.Exception.Message;
break;
}
Все, что вам нужно сделать, это запустить команду от имени этого пользователя, Windows создаст профиль:
psexec.exe -u foobar -p Abcd123! cmd.exe /c exit
https://docs.microsoft.com/en-us/sysinternals/downloads/psexec