Powershell - elevação perde o diretório atual

3

Um problema leva a outro! A ajuda do usuário apenas corrigiu um problema, o que levou a outro à medida que continuei trabalhando neste script. Meu script executa uma verificação para ver se o usuário atual é um administrador da seguinte maneira:

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{   
$arguments = "& '" + $myinvocation.mycommand.definition + "'" + $loc
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}

O argumento para $ loc é um parâmetro que foi originalmente passado por meio de um arquivo em lote que é o seguinte:

@setlocal enableextensions
@cd /d "%~dp0"
SET current="%~dp0
START /WAIT powershell.exe -ExecutionPolicy Bypass -File "JavaInstall.ps1" -loc %current%

Na parte superior do arquivo do Powershell, temos:

param(
[string]$loc
)

Isso funciona sob duas condições:

1) O usuário já é um administrador.
2) A pasta que esta rodando em qualquer ponto na travessia não tem espaço.

Quando isso é executado em uma pasta como: C: \ Usuários \ Usuário \ Desktop \ Java O teste falha de repente. Se eu escrever-host ao longo do caminho, eu posso ver que a variável $ loc está correta até depois da elevação. Depois que eleva, qualquer coisa depois que o espaço é perdido. Se eu executo isso diretamente como um Administrador, ele obviamente ignora a elevação e funciona mesmo com espaços nas pastas, mas eu não quero exigir um cenário de execução de clique com o botão direito do mouse. Alguma idéia do que pode estar causando a perda de texto após o espaço durante a elevação?

    
por Tim P. 28.04.2014 / 22:17

1 resposta

0

Você está lidando com análise de linha de comando múltipla aqui, é por isso que é difícil fazê-lo funcionar corretamente. Você precisa ter aspas em torno de seu caminho com espaços quando passou para o PowerShell (do arquivo bat) e quando passou de do Powershell (para o cmdlet Start-Process ). Isso significa algum escape sério:

  1. Remova a barra invertida arrastada do %~dp0 , ou ele irá mexer com o escape em P.2
  2. Escove aspas com barra invertida ( \ ) para o comando START devido à maneira como o C o analisador de linha de comando funciona :

    A double quotation mark preceded by a backslash, \",
    is interpreted as a literal double quotation mark (").

  3. Escove aspas no PowerShell ao usar Start-Process cmdlet

    1. Para o parâmetro -File :

      "'"$($MyInvocation.MyCommand.Path)'""
      
    2. Para o argumento $Loc :

      "\'"$Loc\'""
      

O exemplo abaixo funciona para mim e mantém o caminho com espaços intactos enquanto se auto eleva.

Lançador de morcegos:

SETLOCAL EnableExtensions

:: Get current directory
SET current=%~dp0

:: Does "current" variable have a trailing slash? If so, remove it
IF %current:~-1%==\ SET current=%current:~,-1%

cd /d %current%

START /WAIT powershell.exe -ExecutionPolicy Bypass -File "JavaInstall.ps1" -Loc \""%current%\""

Código de elevação do PowerShell:

Param(
    [string]$Loc
)

$Delay = 5
Write-Host "'$Loc argument: $Loc"

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
        [Security.Principal.WindowsBuiltInRole] 'Administrator')
)
{
    Write-Host "Not elevated, restarting in $Delay seconds ..."
    Start-Sleep -Seconds $Delay

    $Arguments =  @(
        '-NoProfile',
        '-NoExit',
        '-File',
        "'"$($MyInvocation.MyCommand.Path)'"",
        "\'"$Loc\'""
    )
    Start-Process -FilePath PowerShell.exe -Verb RunAs -ArgumentList $Arguments
    Break
}
else
{
    Write-Host "Already elevated, exiting in $Delay seconds..."
    Start-Sleep -Seconds $Delay
}
    
por 24.02.2015 / 15:56

Tags