Executando um comando como administrador usando o PowerShell?


280

Você sabe como se você é o usuário administrativo de um sistema e pode apenas clicar com o botão direito do mouse em um script em lote e executá-lo como Administrador sem inserir a senha do administrador?

Gostaria de saber como fazer isso com um script do PowerShell. Não quero inserir minha senha; Eu só quero imitar o método com o botão direito do mouse em Executar como administrador .

Tudo o que li até agora exige que você forneça a senha do administrador.


Tente gsudo. Um sudo de código aberto para Windows que permite executar como administrador na linha de comando. Um pop-up do UAC será exibido.
Gerardo Grignoli 20/02

Respostas:


310

Se o console atual não estiver elevado e a operação que você estiver tentando executar exigir privilégios elevados, poderá iniciar o PowerShell com a Run as administratoropção:

PS> Start-Process powershell -Verb runAs

1
Essa parece ser a única maneira de fazê-lo com sucesso. No entanto, a janela do shell adicionada mostra-se problemática em muitos casos. Acabei configurando o que estava invocando o script para ser executado como administrador (por exemplo, através do registro).
Jacek Gorgoń

17
Isso abrirá um novo console em um local diferente. Existe uma maneira de executar como administrador no diretório de trabalho atual?
Container codificado

11
start-process -verb runAs "<cmd>" -argumentlist "<args1> <args2>";)
Dev Anand Sadasivam


1
você pode encontrar o documento aqui: docs.microsoft.com/en-us/powershell/module/... para o arquivo .exe, os verbos podem ser: Open, RunAs, RunAsUser
Kevin Xiong

114

Aqui está uma adição à sugestão de Shay Levi (basta adicionar estas linhas no início de um script):

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))

{   
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}

Isso resulta no script atual sendo passado para um novo processo do PowerShell no modo Administrador (se o Usuário atual tiver acesso ao modo Administrador e o script não for iniciado como Administrador).


6
Isso funcionou para mim:if (-not (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)))
G. Lombard

Modificado facilmente para gerar um erro quando não for executado como administrador. Basta pegar a ifdeclaração e colocar um throwdentro do bloco then.
precisa saber é

2
O comentário de @ G.Lombard teve um erro de sintaxe sutil. Isto é o que funcionou para mim:if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
angularsen

A única sintaxe que trabalhou para mim está no post original, e não a um por G.Lombard nem anjdreas
Nicolas Mommaerts

1
Eu concordo com valor de enumeração ( [Security.Principal.WindowsBuiltInRole]::Administrator)) deve ser preferido ao argumento de cadeia "Administrator"- eu encontrei ambientes endurecidos de segurança com renomeado builtin papéis
Exavier

105

Script do PowerShell com elevação automática

Windows 8.1 / PowerShell 4.0 ou superior

Uma linha :)

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }

# Your script here

141
Bem, tecnicamente falando, tudo é "uma linha" se formatado como esse, mas que não torná-lo real "uma linha"
ilegal-imigrante

3
Desvantagem: se você inserir um não administrador no prompt, encerrará um loop interminável de saída da bifurcação.
Manuel Faux

3
mas isso não passa argumentos
kyb 02/10

2
Para passar args, eu o modifiquei para:if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$args`"" -Verb RunAs; exit }
ab.

2
Esta resposta não preserva o diretório de trabalho. Veja aqui um que faz: stackoverflow.com/a/57035712/2441655
Venryx

45

Benjamin Armstrong postou um excelente artigo sobre scripts do PowerShell com auto-elevação . Há um pequeno problema com seu código; uma versão modificada com base nas correções sugeridas no comentário está abaixo.

Basicamente, ele obtém a identidade associada ao processo atual, verifica se é um administrador e, se não, cria um novo processo do PowerShell com privilégios de administrador e encerra o processo antigo.

# Get the ID and security principal of the current user account
$myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent();
$myWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($myWindowsID);

# Get the security principal for the administrator role
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator;

# Check to see if we are currently running as an administrator
if ($myWindowsPrincipal.IsInRole($adminRole))
{
    # We are running as an administrator, so change the title and background colour to indicate this
    $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)";
    $Host.UI.RawUI.BackgroundColor = "DarkBlue";
    Clear-Host;
}
else {
    # We are not running as an administrator, so relaunch as administrator

    # Create a new process object that starts PowerShell
    $newProcess = New-Object System.Diagnostics.ProcessStartInfo "PowerShell";

    # Specify the current script path and name as a parameter with added scope and support for scripts with spaces in it's path
    $newProcess.Arguments = "& '" + $script:MyInvocation.MyCommand.Path + "'"

    # Indicate that the process should be elevated
    $newProcess.Verb = "runas";

    # Start the new process
    [System.Diagnostics.Process]::Start($newProcess);

    # Exit from the current, unelevated, process
    Exit;
}

# Run your code that needs to be elevated here...

Write-Host -NoNewLine "Press any key to continue...";
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");

Eu não estava recebendo o nome do script e parâmetros devidamente resolvido, então eu envolveu a execução em cmd.exe / c $newProcess = new-object System.Diagnostics.ProcessStartInfo “cmd.exe” $newProcess.Arguments = ‘/c ‘ + [System.Environment]::GetCommandLineArgs() $newProcess.WorkingDirectory = [environment]::CurrentDirectory
xverges

Existe alguma vantagem em fazer isso dessa maneira, em vez de Iniciar o processo? Estou curioso sobre as diferenças, entre este método e os outros postados acima e em outros tópicos. Ambos dependem de .NET, mas este método mais pesadamente ...
ZaxLofful

Eu achei vários comentários associados ao link direto para o post de Armstrong (sentença inicial deste post) muito úteis também.
BentChainRing

2
Esta resposta não preserva o diretório de trabalho. Veja aqui um que faz: stackoverflow.com/a/57035712/2441655
Venryx

22

Você pode criar um arquivo em lotes ( *.bat) que executa o script do PowerShell com privilégios administrativos ao clicar duas vezes. Dessa forma, você não precisa alterar nada no script do PowerShell . Para fazer isso, crie um arquivo em lotes com o mesmo nome e local do script do PowerShell e coloque nele o seguinte conteúdo:

@echo off

set scriptFileName=%~n0
set scriptFolderPath=%~dp0
set powershellScriptFileName=%scriptFileName%.ps1

powershell -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"%scriptFolderPath%\`\"; & \`\".\%powershellScriptFileName%\`\"`\"\" -Verb RunAs"

É isso aí!

Aqui está a explicação:

Supondo que o script do PowerShell esteja no caminho C:\Temp\ScriptTest.ps1, seu arquivo em lotes deve ter o caminho C:\Temp\ScriptTest.bat. Quando alguém executa esse arquivo em lotes, as seguintes etapas ocorrerão:

  1. O cmd executará o comando

    powershell -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"C:\Temp\`\"; & \`\".\ScriptTest.ps1\`\"`\"\" -Verb RunAs"
  2. Uma nova sessão do PowerShell será aberta e o seguinte comando será executado:

    Start-Process powershell "-ExecutionPolicy Bypass -NoProfile -NoExit -Command `"cd \`"C:\Temp\`"; & \`".\ScriptTest.ps1\`"`"" -Verb RunAs
  3. Outra nova sessão do PowerShell com privilégios administrativos será aberta na system32pasta e os seguintes argumentos serão passados ​​para ela:

    -ExecutionPolicy Bypass -NoProfile -NoExit -Command "cd \"C:\Temp\"; & \".\ScriptTest.ps1\""
  4. O seguinte comando será executado com privilégios administrativos:

    cd "C:\Temp"; & ".\ScriptTest.ps1"

    Uma vez que os argumentos do caminho e nome do script são aspas duplas, eles podem conter espaço ou caracteres de aspas simples ( ').

  5. A pasta atual mudará de system32para C:\Tempe o script ScriptTest.ps1será executado. Depois que o parâmetro -NoExitfor passado, a janela não será fechada, mesmo que o script do PowerShell gere alguma exceção.


Se fizer isso, recebo um pop-up perguntando se eu permito que o PowerShell faça alterações no meu sistema. Isso torna inutilizável para automação.
precisa saber é o seguinte

@JohnSlegers, se você precisar automatizá-lo, é sua responsabilidade garantir que o processo automatizado seja executado como administrador. Se você pudesse elevar automaticamente um processo não administrativo a um processo administrativo sem a interação do usuário, isso anularia a finalidade de exigir que um processo tenha privilégios de administrador em primeiro lugar.
meustrus 17/06/19

@meustrus: Como engenheiro de lançamento , meu trabalho envolve a criação e manutenção de processos de compilação que são executados automaticamente, periodicamente ou quando determinados critérios são atendidos. Alguns desses processos precisam de privilégios de administrador, e exigir entrada do usuário torna um processo inutilizável nesse contexto. - No Linux, você pode conseguir isso usando o sudocomando e configurando o usuário no processo automatizado NOPASSWD: ALLno sudoersarquivo .
John Slegers

1
Essa é uma resposta melhor que as outras, pois preserva o diretório de trabalho. Eu coloquei alguns de uma linha variantes desta abordagem aqui (uma para cmd / batch, um para Explorador entradas-menu de contexto, e um para powershell): stackoverflow.com/a/57033941/2441655
Venryx

17

Aqui está um trecho auto-elevável para scripts do Powershell que preserva o diretório de trabalho :

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`"";
    exit;
}

# Your script here

Preservar o diretório de trabalho é importante para scripts que executam operações relativas ao caminho. Quase todas as outras respostas não preservam esse caminho, o que pode causar erros inesperados no restante do script.

Se você preferir não usar um script / snippet auto-elevável e desejar apenas uma maneira fácil de iniciar um script como administrador (por exemplo, no menu de contexto do Explorer), veja minha outra resposta aqui: https: // stackoverflow .com / a / 57033941/2441655


16

Usando

#Requires -RunAsAdministrator

ainda não foi declarado. Parece estar lá apenas desde o PowerShell 4.0.

http://technet.microsoft.com/en-us/library/hh847765.aspx

Quando esse parâmetro de opção é adicionado à sua instrução require, ele especifica que a sessão do Windows PowerShell na qual você está executando o script deve ser iniciada com direitos de usuário elevados (Executar como Administrador).

Para mim, isso parece ser uma boa maneira de fazer isso, mas ainda não tenho certeza da experiência de campo. Os tempos de execução do PowerShell 3.0 provavelmente ignoram isso ou, pior ainda, dão um erro.

Quando o script é executado como um não administrador, o seguinte erro é fornecido:

O script 'StackOverflow.ps1' não pode ser executado porque contém uma instrução "#requires" para execução como Administrador. A sessão atual do Windows PowerShell não está sendo executada como Administrador. Inicie o Windows PowerShell usando a opção Executar como administrador e tente executar o script novamente.

+ CategoryInfo          : PermissionDenied: (StackOverflow.ps1:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ScriptRequiresElevation

7
Infelizmente, tudo o que faz é fazer com que o script falhe com um erro se o shell não tiver privilégios de administrador. Não eleva por si só.
Jacek Gorgoń 02/02

O PS3 parece dar um erro, conforme sugerido. Eu entendo Parameter RunAsAdministrator requires an argument. @akauppi Não estou convencido de que eles sempre estejam pensando.
jpmc26

14

Você pode adicionar facilmente algumas entradas do registro para obter um menu de contexto "Executar como administrador" para .ps1arquivos:

New-Item -Path "Registry::HKEY_CLASSES_ROOT\Microsoft.PowershellScript.1\Shell\runas\command" `
-Force -Name '' -Value '"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit "%1"'

(atualizado para um script mais simples do @ Shay)

Basicamente, HKCR:\Microsoft.PowershellScript.1\Shell\runas\commanddefina o valor padrão para chamar o script usando o Powershell.


Não funciona, você está criando uma chave '(padrão)', não atualizando o valor da chave '(padrão)'. Consegui condensar o código em uma linha que funciona para mim. Você pode testá-lo? New-Item -Path "Registry :: HKEY_CLASSES_ROOT \ Microsoft.PowershellScript.1 \ Shell \ runas \ command" -Force -Name '' -Value '"c: \ windows \ system32 \ windowspowershell \ v1.0 \ powershell.exe" -noexit "% 1" '
Shay Levy

@ Shay Levy - Oi Shay, obrigado pela atualização. Eu atualizei a resposta com ele. Isso funciona. Mas o que eu tinha trabalhado também, apesar de detalhado. Eu não tinha feito muita edição de registro com o Powershell, mas fazê-lo com "(padrão)" era algo que eu tinha visto como exemplo. Ele não criou uma nova chave (que algo como o padrão teria), mas atualizou a chave padrão conforme o esperado. Você experimentou ou adivinhou da (default)parte?
manojlds

Eu tentei. Criou uma chave '(padrão)' sob a chave de comando.
Shay Levy

Isso funcionou para mim após algumas pequenas alterações no valor do registro: "c: \ windows \ system32 \ windowspowershell \ v1.0 \ powershell.exe" -ExecutionPolicy RemoteSigned -NoExit "& '% 1'"
MikeBaz - MSFT

1
O valor do registro na resposta tem todos os tipos de problemas. Na verdade, ele não executa o comando e não cita corretamente o nome do script (o que significa que quebra nos caminhos com espaços). Estou usando o seguinte com êxito:"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit -command "& '%1'"
Kal Zekdor 4/17/17

10

O código postado por Jonathan e Shay Levy não funcionou para mim.

Encontre o código de trabalho abaixo:

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{   
#"No Administrative rights, it will display a popup window asking user for Admin rights"

$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments

break
}
#"After user clicked Yes on the popup, your file will be reopened with Admin rights"
#"Put your code here"

2
Solução muito útil e prática: apenas a perpendi ao meu script e funciona.
CDuv

3
@Abatonime Que tal você apontar que é fácil perder diferenças para o benefício de seus leitores? Honestamente, essa mudança não vale mais do que um comentário sobre a outra resposta.
precisa saber é o seguinte

8

Você precisa executar novamente o script com privilégios administrativos e verificar se o script foi iniciado nesse modo. Abaixo, escrevi um script que tem duas funções: DoElevatedOperations e DoStandardOperations . Você deve colocar seu código que requer direitos de administrador no primeiro e operações padrão no segundo. o variável IsRunAsAdmin é usada para identificar o modo de administrador.

Meu código é uma extração simplificada do script da Microsoft que é gerada automaticamente quando você cria um pacote de aplicativos para aplicativos da Windows Store.

param(
    [switch]$IsRunAsAdmin = $false
)

# Get our script path
$ScriptPath = (Get-Variable MyInvocation).Value.MyCommand.Path

#
# Launches an elevated process running the current script to perform tasks
# that require administrative privileges.  This function waits until the
# elevated process terminates.
#
function LaunchElevated
{
    # Set up command line arguments to the elevated process
    $RelaunchArgs = '-ExecutionPolicy Unrestricted -file "' + $ScriptPath + '" -IsRunAsAdmin'

    # Launch the process and wait for it to finish
    try
    {
        $AdminProcess = Start-Process "$PsHome\PowerShell.exe" -Verb RunAs -ArgumentList $RelaunchArgs -PassThru
    }
    catch
    {
        $Error[0] # Dump details about the last error
        exit 1
    }

    # Wait until the elevated process terminates
    while (!($AdminProcess.HasExited))
    {
        Start-Sleep -Seconds 2
    }
}

function DoElevatedOperations
{
    Write-Host "Do elevated operations"
}

function DoStandardOperations
{
    Write-Host "Do standard operations"

    LaunchElevated
}


#
# Main script entry point
#

if ($IsRunAsAdmin)
{
    DoElevatedOperations
}
else
{
    DoStandardOperations
}

7

Adicionando meus 2 centavos. Minha versão simples baseada em net session, que funciona o tempo todo até agora no Windows 7 / Windows 10. Por que complicar demais?

if (!(net session)) {$path =  "& '" + $myinvocation.mycommand.definition + "'" ; Start-Process powershell -Verb runAs -ArgumentList $path ; exit}

basta adicionar na parte superior do script e ele será executado como administrador.


1
existe uma maneira de enviar uma mensagem ao usuário após a exibição do "Acesso negado"?
ycomp 7/02/19

... ou para evitar a mensagem de todos os
modos

1
@ GünterZöchbauer if (!(net session 2>&1 | Out-Null)) { ... @ycomp ... } else { echo "your message" }.
Matthieu

obtendo erros para isso,cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
user2305193

1
@ user2305193 Set-ExecutionPolicy -ExecutionPolicy <PolicyName>, você pode configurá-lo como bypass Mas bypasspode ser perigoso. Configurá-lo paraAllSigned
AliFurkan

5

Esse comportamento é por design. Existem várias camadas de segurança, já que a Microsoft realmente não queria que os arquivos .ps1 fossem o mais recente vírus de email. Algumas pessoas acham que isso é contrário à própria noção de automação de tarefas, que é justa. O modelo de segurança do Vista + é "des-automatizar" as coisas, fazendo com que o usuário as aceite.

No entanto, eu suspeito que, se você iniciar o PowerShell como elevado, ele poderá executar arquivos em lote sem solicitar a senha novamente até fechar o PowerShell.


5

Você também pode forçar o aplicativo a abrir como administrador, se você tiver uma conta de administrador, é claro.

insira a descrição da imagem aqui

Localize o arquivo, clique com o botão direito do mouse em> propriedades> Atalho> Avançado e marque Executar como Administrador

Clique em OK.


1
Como você escreve isso?
Dieter

4

C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShellé onde reside o atalho do PowerShell. Ele também ainda vai para um local diferente para invocar o 'exe' real ( %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe).

Como o PowerShell é orientado por perfil de usuário quando se trata de permissões; se seu nome de usuário / perfil tiver permissões para fazer algo, então, nesse perfil, no PowerShell você também poderá fazê-lo. Dito isto, faria sentido que você alterasse o atalho localizado no seu perfil de usuário, por exemplo,C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell ,.

Clique com o botão direito do mouse e clique em Propriedades. Clique no botão "Avançado" na guia "Atalho", localizado logo abaixo do campo de texto "Comentários", ao lado direito de outros dois botões, "Abrir local do arquivo" e "Alterar ícone", respectivamente.

Marque a caixa de seleção "Executar como administrador". Clique OK, então Applye OK. Mais uma vez, clique com o botão direito do mouse no ícone 'Windows PowerShell' localizado em C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShelle selecione "Fixar no menu Iniciar / barra de tarefas".

Agora, sempre que você clicar nesse ícone, ele chamará o UAC para escalação. Depois de selecionar 'SIM', você notará o console do PowerShell aberto e será rotulado como "Administrador" na parte superior da tela.

Para dar um passo adiante ... você pode clicar com o botão direito do mouse no mesmo atalho de ícone no local do seu perfil do Windows PowerShell e atribuir um atalho de teclado que fará exatamente a mesma coisa que se você clicasse no ícone adicionado recentemente. Então, onde está escrito "Tecla de atalho", coloque uma combinação de teclas / botões do teclado como: Ctrl+ Alt+ P P(para PowerShell) . Clique Applye OK.

Agora tudo o que você precisa fazer é pressionar a combinação de botões que você atribuiu e você verá o UAC ser chamado. Depois de selecionar 'SIM', você verá um console do PowerShell aparecer e "Administrador" exibido na barra de título.


Cara :) A palavra-chave na pergunta do OP é script !! Não é uma solução de clique com o mouse na interface do usuário.
Christian

3

Eu encontrei uma maneira de fazer isso ...

Crie um arquivo em lotes para abrir seu script:

@echo off
START "" "C:\Scripts\ScriptName.ps1"

Em seguida, crie um atalho, na área de trabalho, digamos (clique com o botão direito do mouse em Novo -> Atalho ).

Em seguida, cole-o no local:

C:\Windows\System32\runas.exe /savecred /user:*DOMAIN*\*ADMIN USERNAME* C:\Scripts\BatchFileName.bat

Ao abrir pela primeira vez, você precisará digitar sua senha uma vez. Isso o salvará no gerenciador de credenciais do Windows.

Depois disso, você poderá executar como administrador sem precisar digitar um nome de usuário ou senha de administrador.


/ savecred não é seguro!
18716 Nathan Goings

Esta é a única solução que não usa o prompt de elevação gráfica que pode não estar acessível em uma sessão remota.
DustWolf

3

O problema com as respostas @pgk e @Andrew Odri é quando você tem parâmetros de script, especialmente quando são obrigatórios. Você pode resolver esse problema usando a seguinte abordagem:

  1. O usuário clica com o botão direito do mouse no arquivo .ps1 e seleciona 'Executar com PowerShell': solicite os parâmetros por meio de caixas de entrada (essa é uma opção muito melhor do que usar o atributo de parâmetro HelpMessage );
  2. O usuário executa o script através do console: permita que ele passe os parâmetros desejados e permita que o console o force a informar os obrigatórios.

Aqui está como seria o código se o script tivesse o ComputerName e parâmetros obrigatórios Port :

[CmdletBinding(DefaultParametersetName='RunWithPowerShellContextMenu')]
param (
    [parameter(ParameterSetName='CallFromCommandLine')]
    [switch] $CallFromCommandLine,

    [parameter(Mandatory=$false, ParameterSetName='RunWithPowerShellContextMenu')]
    [parameter(Mandatory=$true, ParameterSetName='CallFromCommandLine')]
    [string] $ComputerName,

    [parameter(Mandatory=$false, ParameterSetName='RunWithPowerShellContextMenu')]
    [parameter(Mandatory=$true, ParameterSetName='CallFromCommandLine')]
    [UInt16] $Port
)

function Assert-AdministrativePrivileges([bool] $CalledFromRunWithPowerShellMenu)
{
    $isAdministrator = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

    if ($isAdministrator)
    {
        if (!$CalledFromRunWithPowerShellMenu -and !$CallFromCommandLine)
        {
            # Must call itself asking for obligatory parameters
            & "$PSCommandPath" @script:PSBoundParameters -CallFromCommandLine
            Exit
        }
    }
    else
    {
        if (!$CalledFromRunWithPowerShellMenu -and !$CallFromCommandLine)
        {
            $serializedParams = [Management.Automation.PSSerializer]::Serialize($script:PSBoundParameters)

            $scriptStr = @"
                `$serializedParams = '$($serializedParams -replace "'", "''")'

                `$params = [Management.Automation.PSSerializer]::Deserialize(`$serializedParams)

                & "$PSCommandPath" @params -CallFromCommandLine
"@

            $scriptBytes = [System.Text.Encoding]::Unicode.GetBytes($scriptStr)
            $encodedCommand = [Convert]::ToBase64String($scriptBytes)

            # If this script is called from another one, the execution flow must wait for this script to finish.
            Start-Process -FilePath 'powershell' -ArgumentList "-ExecutionPolicy Bypass -NoProfile -EncodedCommand $encodedCommand" -Verb 'RunAs' -Wait
        }
        else
        {
            # When you use the "Run with PowerShell" feature, the Windows PowerShell console window appears only briefly.
            # The NoExit option makes the window stay visible, so the user can see the script result.
            Start-Process -FilePath 'powershell' -ArgumentList "-ExecutionPolicy Bypass -NoProfile -NoExit -File ""$PSCommandPath""" -Verb 'RunAs'
        }

        Exit
    }
}

function Get-UserParameters()
{
    [string] $script:ComputerName = [Microsoft.VisualBasic.Interaction]::InputBox('Enter a computer name:', 'Testing Network Connection')

    if ($script:ComputerName -eq '')
    {
        throw 'The computer name is required.'
    }

    [string] $inputPort = [Microsoft.VisualBasic.Interaction]::InputBox('Enter a TCP port:', 'Testing Network Connection')

    if ($inputPort -ne '')
    {
        if (-not [UInt16]::TryParse($inputPort, [ref]$script:Port))
        {
            throw "The value '$inputPort' is invalid for a port number."
        }
    }
    else
    {
        throw 'The TCP port is required.'
    }
}

# $MyInvocation.Line is empty in the second script execution, when a new powershell session
# is started for this script via Start-Process with the -File option.
$calledFromRunWithPowerShellMenu = $MyInvocation.Line -eq '' -or $MyInvocation.Line.StartsWith('if((Get-ExecutionPolicy')

Assert-AdministrativePrivileges $calledFromRunWithPowerShellMenu

# Necessary for InputBox
[System.Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') | Out-Null

if ($calledFromRunWithPowerShellMenu)
{
    Get-UserParameters
}

# ... script code
Test-NetConnection -ComputerName $ComputerName -Port $Port

3

Várias respostas aqui são próximas, mas um pouco mais de trabalho do que o necessário.

Crie um atalho para o seu script e configure-o para "Executar como Administrador":

  • Crie o atalho.
  • Clique com o botão direito do mouse em atalho e abra Properties...
  • Editar Targetde<script-path> parapowershell <script-path>
  • Clique Advanced...e ativeRun as administrator

2

Outra solução mais simples é que você também pode clicar com o botão direito do mouse em "C: \ Windows \ System32 \ cmd.exe" e escolher "Executar como Administrador" e executar qualquer aplicativo como administrador sem fornecer nenhuma senha.


2

Estou usando a solução abaixo. Ele lida com stdout / stderr via recurso de transcrição e passa o código de saída corretamente para o processo pai. Você precisa ajustar o caminho da transcrição / nome do arquivo.

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{ 
  echo "* Respawning PowerShell child process with elevated privileges"
  $pinfo = New-Object System.Diagnostics.ProcessStartInfo
  $pinfo.FileName = "powershell"
  $pinfo.Arguments = "& '" + $myinvocation.mycommand.definition + "'"
  $pinfo.Verb = "RunAs"
  $pinfo.RedirectStandardError = $false
  $pinfo.RedirectStandardOutput = $false
  $pinfo.UseShellExecute = $true
  $p = New-Object System.Diagnostics.Process
  $p.StartInfo = $pinfo
  $p.Start() | Out-Null
  $p.WaitForExit()
  echo "* Child process finished"
  type "C:/jenkins/transcript.txt"
  Remove-Item "C:/jenkins/transcript.txt"
  Exit $p.ExitCode
} Else {
  echo "Child process starting with admin privileges"
  Start-Transcript -Path "C:/jenkins/transcript.txt"
}

# Rest of your script goes here, it will be executed with elevated privileges

Isso perde todos os argumentos de invocação
Guillermo Prandi

2

Aqui está como executar um comando do powershell elevado e coletar seu formulário de saída em um arquivo em lotes do Windows em um único comando (ou seja, não gravar um script do powershell ps1).

powershell -Command 'Start-Process powershell -ArgumentList "-Command (Get-Process postgres | Select-Object Path | Select-Object -Index 0).Path | Out-File -encoding ASCII $env:TEMP\camp-postgres.tmp" -Verb RunAs'

Acima, você vê, primeiro, inicio um PowerShell com prompt elevado e, em seguida, peço que inicie outro PowerShell (sub shell) para executar o comando.


1

Além da resposta de Shay Levy, siga a configuração abaixo (apenas uma vez)

  1. Inicie um PowerShell com direitos de administrador.
  2. Pergunta sobre o estouro de pilha no seguimento O PowerShell diz que "a execução de scripts está desabilitada neste sistema". .
  3. Coloque o arquivo .ps1 em qualquer uma das PATHpastas, por exemplo. Pasta Windows \ System32

Após a instalação:

  1. Pressione Win+R
  2. Invocar powershell Start-Process powershell -Verb runAs <ps1_file>

Agora você pode executar tudo em apenas uma linha de comando. O acima funciona no Windows 8 Basic de 64 bits.


1

A maneira mais confiável que eu encontrei é envolvê-lo em um arquivo .bat auto-elevável:

@echo off
NET SESSION 1>NUL 2>NUL
IF %ERRORLEVEL% EQU 0 GOTO ADMINTASKS
CD %~dp0
MSHTA "javascript: var shell = new ActiveXObject('shell.application'); shell.ShellExecute('%~nx0', '', '', 'runas', 0); close();"
EXIT

:ADMINTASKS

powershell -file "c:\users\joecoder\scripts\admin_tasks.ps1"

EXIT

O .bat verifica se você já é administrador e reinicia o script como administrador, se necessário. Também impede que janelas "cmd" estranhas se abram com o quarto parâmetro de ShellExecute()definido como 0.


Boa resposta, mas tentei e não funcionei (e saí da linha de comando da qual a chamei). Corrigi assim: mudei o primeiro EXITpara a GOTO :EOFe excluí o segundo. Além disso, o AND cd %~dp0deve ser cd /d %~dp0o primeiro comando após o @echo off. Dessa forma, você não precisa do caminho absoluto dos .ps1dois, apenas coloque-o na mesma pasta que o .bat. Se você precisar ver o resultado, altere o quarto parâmetro para 1.
Cdlvcdlv

Qual sistema operacional e versão você está executando?
21818 Joe Coder

Windows 7 SP1 Ultimate. Eu tenho sistema em C: mas também dados e aplicativos portáteis em D: principalmente (e várias outras unidades). A propósito ... e se o programa / script usar parâmetros? Qual seria o mshtacomando?
Cdlvcdlv

Eu acho que você pode ter errado no seu teste, porque o script funciona muito bem. A propósito, ele foi projetado para sair do cmdprocesso de chamada , para que não o "conserte", mas estou feliz por você poder modificá-lo de acordo com suas necessidades.
precisa saber é o seguinte

Ok, se você quiser sair do cmd(eu não fiz). Mas com relação às outras mudanças, acho que são correções, porque minha versão funcionaria para nós dois, enquanto a sua não funciona para mim, ou seja, a minha é mais geral (aborda o cenário de unidades diferentes). Enfim, uma abordagem muito inteligente.
Cdlvcdlv

0

Eu nunca vi minha própria maneira de fazer isso antes, então tente isso. É muito mais fácil seguir e tem uma pegada muito menor:

if([bool]([Security.Principal.WindowsIdentity]::GetCurrent()).Groups -notcontains "S-1-5-32-544") {
    Start Powershell -ArgumentList "& '$MyInvocation.MyCommand.Path'" -Verb runas
    }

Muito simplesmente, se a sessão atual do Powershell tiver sido chamada com privilégios de administrador, o SID conhecido do Grupo de Administradores aparecerá nos Grupos quando você capturar a identidade atual. Mesmo se a conta for membro desse grupo, o SID não será exibido, a menos que o processo tenha sido invocado com credenciais elevadas.

Quase todas essas respostas são uma variação do método imensamente popular de Ben Armstrong, da Microsoft, de como realizá-lo, sem realmente entender o que está realmente fazendo e de que outra forma imitar a mesma rotina.


0

Para anexar a saída do comando a um nome de arquivo de texto que inclua a data atual, você pode fazer algo assim:

$winupdfile = 'Windows-Update-' + $(get-date -f MM-dd-yyyy) + '.txt'
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -Command `"Get-WUInstall -AcceptAll | Out-File $env:USERPROFILE\$winupdfile -Append`"" -Verb RunAs; exit } else { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -Command `"Get-WUInstall -AcceptAll | Out-File $env:USERPROFILE\$winupdfile -Append`""; exit }

0

Este é um esclarecimento ...

A credencial RUNAS / SAVECRED do powershell "não é segura", tentou e adiciona a identidade e a senha de administrador ao cache de credenciais e pode ser usada em outro lugar OOPS !. Se você fez isso, sugiro que verifique e remova a entrada.

Revise seu programa ou código, pois a política da Microsoft é que você não pode ter código misto de usuário e administrador no mesmo blob de código sem o UAC (o ponto de entrada) para executar o programa como administrador. Isso seria sudo (a mesma coisa) no Linux.

O UAC possui 3 tipos, não veja, um prompt ou um ponto de entrada gerado no manifesto do programa. Ele não eleva o programa, portanto, se não houver UAC e precisar de administração, ele falhará. O UAC, embora como um requisito de administrador, seja bom, evita a execução de código sem autenticação e o cenário de códigos mistos em execução no nível do usuário.


Isso deve ser um comentário, não é uma solução para a pergunta (exatamente como o fórum funciona; seu conteúdo é útil, mas não é uma solução).
precisa saber é o seguinte

-2

Acontece que foi muito fácil. Tudo o que você precisa fazer é executar um cmd como administrador. Em seguida, digite explorer.exee pressione Enter. Isso abre o Windows Explorer . Agora clique com o botão direito do mouse no script do PowerShell que você deseja executar, escolha "executar com o PowerShell", que o iniciará no PowerShell no modo de administrador.

Pode solicitar que você ative a política, digite Y e pressione enter. Agora, o script será executado no PowerShell como administrador. Caso esteja tudo vermelho, significa que sua política ainda não foi afetada. Em seguida, tente novamente e deve funcionar bem.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.