Você tem a permissão, mas está desativado . Isso é o que o PowerShell está lhe dizendo.
Para o sistema de desligamento, use a função Win32API chamada InitiateSystemShutdown
ou ExitWindowsEx
:
ExitWindowsEx(EWX_POWEROFF, 0);
Estas funções apontam:
To shut down the local computer, the calling thread must have the SE_SHUTDOWN_NAME privilege. By default, users can enable the SE_SHUTDOWN_NAME privilege on the computer they are logged onto, and administrators can enable the SE_REMOTE_SHUTDOWN_NAME privilege on remote computers.
Como você pode ver, o Windows verifica os privilégios thread (qualquer thread tem um token com privilégios). Se você chamar ExitWindowsEx
sem o privilégio SE_SHUTDOWN_NAME , a função falhará com o erro:
Error code: 1314
A required privilege is not held by the client
Os tópicos que você cria por padrão herdam seus privilégios; mas um programa pode ativar um privilégio desativado que foi concedido usando AdjustTokenPrivileges
:
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = LookupPrivilegeValue(NULL, "SeShutdownPrivilege");
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
HANDLE processToken = OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES);
AdjustTokenPrivileges(processToken, false, tp, 0, NULL, NULL);
CloseHandle(processToken);
Alteração de privilégios em um token diz :
AdjustTokenPrivileges
cannot add or remove privileges from the token. It can only enable existing privileges that are currently disabled or disable existing privileges that are currently enabled
Então, por que esse privilégio é desativado por padrão? Para se certificar de que nenhum programa pode desligar o Windows por acidente. As aplicações devem pedir isso explicitamente.
Existe um livro antigo, mas muito bom: link sobre todas essas coisas.