В скрипте PowerShell, как я могу проверить, запускаю ли я его с правами администратора?

Вопрос или проблема

В скрипте PowerShell, как я могу проверить, запущен ли я с правами администратора?

$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

(из Командные приемы безопасности)


Чтобы скрипт не выполнялся, если не запущен от имени администратора:

#Requires -RunAsAdministrator

https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_requires

Вывод:

Скрипт ‘MyScript.ps1’ не может быть выполнен, потому что он содержит оператор “#requires” для выполнения от имени администратора. Текущая сессия Windows PowerShell не запускается от имени администратора. Запустите Windows PowerShell с помощью параметра “Запуск от имени администратора”, а затем попробуйте снова выполнить скрипт.

Представлено в PowerShell 4.0.

function Test-Administrator  
{  
    $user = [Security.Principal.WindowsIdentity]::GetCurrent();
    (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)  
}

Выполните вышеуказанную функцию. Если результат равен True, у пользователя есть права администратора.

В качестве комбинации приведенных выше ответов вы можете использовать что-то похожее на следующее в начале вашего скрипта:

# todo: поместите это в отдельный файл для повторного использования и подключите его
function Test-Administrator  
{  
    [OutputType([bool])]
    param()
    process {
        [Security.Principal.WindowsPrincipal]$user = [Security.Principal.WindowsIdentity]::GetCurrent();
        return $user.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator);
    }
}

if(-not (Test-Administrator))
{
    # TODO: определить правильные коды выхода для указанных ошибок 
    Write-Error "Этот скрипт должен выполняться от имени администратора.";
    exit 1;
}

$ErrorActionPreference = "Stop";

# выполнить что-то

Другой метод — начать ваш скрипт с этой строки, которая предотвратит его выполнение, если он не был запущен с правами администратора.

#Requires -RunAsAdministrator

Это проверит, являетесь ли вы администратором, если нет, то он снова откроется в PowerShell ISE как администратор.

Надеюсь, это поможет!

    $ver = $host | select version
    if ($ver.Version.Major -gt 1)  {$Host.Runspace.ThreadOptions = "ReuseThread"}

    # Проверьте, что пользователь, запускающий скрипт, является администратором
    $IsAdmin=[Security.Principal.WindowsIdentity]::GetCurrent()
    If ((New-Object Security.Principal.WindowsPrincipal $IsAdmin).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) -eq $FALSE)
    {
      "`nОШИБКА: Вы не являетесь локальным администратором. Запустите этот скрипт после входа в систему с учетной записью локального администратора."
        # Мы не запускаемся "как администратор" - поэтому перезапускаем как администратор

        # Создайте новый объект процесса, который запускает PowerShell
        $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell_ise";

        # Укажите путь и имя текущего скрипта в качестве параметра
        $newProcess.Arguments = $myInvocation.MyCommand.Definition;

        # Укажите, что процесс должен быть с повышенными правами
        $newProcess.Verb = "runas";

        # Запустите новый процесс
        [System.Diagnostics.Process]::Start($newProcess);

        # Выйдите из текущего процесса без повышенных прав
        exit
    }

Вот мой подход: если скрипт не запущен как администратор, он перезагружает его и запрашивает доступ администратора

if (-not (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
# Запросите у пользователя повышенные права для выполнения скрипта
$arguments = "& '" + $myInvocation.MyCommand.Definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
exit
}

function Test-RunAsAdministrator{
   $script = new-item -path $env:TEMP -name 'TestElevated.ps1' -value @'
      #Requires -RunAsAdministrator
      $true
'@
   
   try{
      & $script.FullName
   }catch [System.Management.Automation.ScriptRequiresException]{
      $false
   }finally{
      remove-item $script.FullName
   }
}

Это обертка функции для оператора #Requires, она должна возвращать:

  • $true, когда выполнена в повышенном контексте
  • $false, когда выполнена в контексте без повышения

Хотя в моих текущих сценариях тестирования она предоставляет те же результаты, что и использование GetCurrent()

Администратор Не администратор
Повышенный процесс $true N/A
Неповышенный процесс $false $false
$IsAdministrator = ([Security.Principal.WindowsPrincipal]::new(
   ($id = [Security.Principal.WindowsIdentity]::GetCurrent())
)).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
$id.dispose(); remove-variable id

МЕНЬШЕ – ЭТО БОЛЬШЕ

Небольшой код (Fltmc.exe).Count -eq 3 даст True / False. Потому что количество всегда 3 в non-admin.

If ((Fltmc.exe).Count -eq 3) {'Я Я.Ю.И.Р'} else {'Я Я.Д.М.И.Н'}; Pause

Используя функцию:

Function IsAdmin {(Fltmc.exe).Count -ne 3}

Тогда IsAdmin, вывод True / False

источник: fltmc.exe

#! pwsh

function IsAdmin() {
    $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object System.Security.Principal.WindowsPrincipal($identity)
    $isAdmin = $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
    return $isAdmin
}

function RestartWithAdmin()
{
    $scriptPath = Resolve-Path $Script:MyInvocation.MyCommand.Path
    # если вы хотите отладить, добавьте опцию '-noe' к $arguments
    $arguments = @("-nop", "-nol", "-ex", "RemoteSigned", "-f", "$scriptPath")
    Start-Process pwsh -ArgumentList $arguments -Verb RunAs -Wait -PassThru
    exit
}

if (-not (IsAdmin)) {
    RestartWithAdmin
}

Write-Host "Эта строка достигается только тогда, когда скрипт имеет права администратора"

Просто еще один простой ответ:

$isAdmin = (Get-Process -Name PowerShell -IncludeUserName).UserName.Contains('\Administrator')

Это вернет True, если текущий процесс PowerShell запущен под учетной записью администратора.

Ответ или решение

Вопрос: как в скрипте PowerShell проверить, запущен ли он с правами администратора, требует внимательного подхода. Приведенные ниже методы и функции помогут вам установить, есть ли у вас необходимые привилегии.

Метод 1: Использование класса WindowsPrincipal

Одним из самых распространенных и простых способов проверки является использование конструкции класса WindowsPrincipal. Вот как это сделать:

$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if ($isAdmin) {
    Write-Host "Вы запущены с правами администратора."
} else {
    Write-Error "Вы не запущены с правами администратора."
}

Данный код создает объект, представляющий текущего пользователя, и проверяет, находится ли он в роли администратора.

Метод 2: Функция для проверки прав администратора

Создание функции для проверки прав также является удобным решением. Это позволяет повторно использовать код в разных частях вашего скрипта.

function Test-Administrator {
    $user = [Security.Principal.WindowsIdentity]::GetCurrent()
    return (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

if (-not (Test-Administrator)) {
    Write-Error "Этот скрипт должен быть выполнен от имени администратора."
    exit 1
}

# Продолжение выполнения скрипта

Метод 3: Автоматический запуск с повышенными правами

Если требуется автоматическое перезапускание скрипта с правами администратора, можно использовать следующий подход:

if (-not (Test-Administrator)) {
    $arguments = "& '" + $myInvocation.MyCommand.Definition + "'"
    Start-Process powershell -Verb runAs -ArgumentList $arguments
    exit
}

Данный код автоматически перезапускает текущий скрипт с повышенными правами, если он был запущен без них.

Метод 4: Использование директивы #Requires

Начиная с PowerShell версии 4.0, вы можете использовать директиву #Requires, чтобы запретить выполнение скрипта, если он не запущен с правами администратора.

#Requires -RunAsAdministrator

Если скрипт запущен от имени обычного пользователя, вы получите сообщение об ошибке. Этот метод прост и эффективен для обеспечения выполнения необходимых операций.

Метод 5: Проверка условий через Fltmc.exe

Еще один способ проверить, запущен ли вы с правами администратора, – это использование утилиты fltmc.exe:

If ((Fltmc.exe).Count -eq 3) {
    Write-Host 'Вы не обладаете правами администратора.'
} else {
    Write-Host 'Вы обладаете правами администратора.'
}

Заключение

В зависимости от ваших нужд вы можете выбирать любой из упомянутых методов для проверки административных привилегий в PowerShell. Они обеспечивают гибкость и могут быть адаптированы для выполнения различных сценариев. Используя эти решения, вы сможете оптимизировать свою работу и избежать потенциальных проблем, связанных с недостатком прав.

Оцените материал
Добавить комментарий

Капча загружается...