pt.phhsnews.com


pt.phhsnews.com / Como usar um arquivo em lotes para tornar os scripts do PowerShell mais fáceis de executar

Como usar um arquivo em lotes para tornar os scripts do PowerShell mais fáceis de executar


Por vários motivos, principalmente relacionados à segurança, os scripts do PowerShell não são tão portáteis e fáceis de usar quanto os scripts em lote. No entanto, podemos agrupar um script em lote com nossos scripts do PowerShell para solucionar esses problemas. Aqui, mostraremos algumas dessas áreas problemáticas e como construir um script em lote para contorná-las.

Por que não posso simplesmente copiar meu arquivo .PS1 para outro computador e executá-lo?

A menos que o sistema de destino tenha sido pré-configurado para permitir a execução de scripts arbitrários, com os privilégios necessários e usando as configurações corretas, é provável que você tenha alguns problemas ao tentar fazer isso.

  1. O PowerShell é não associado à extensão de arquivo .PS1 por padrão. Trouxemos isso inicialmente em nossa série PowerShell Geek School. O Windows associa arquivos .PS1 ao Bloco de notas por padrão, em vez de enviá-los ao interpretador de comandos do PowerShell. Isso evita a execução acidental de scripts mal-intencionados simplesmente clicando duas vezes neles. Há maneiras de mudar esse comportamento, mas provavelmente não é algo que você queira fazer em todos os computadores em que está conduzindo seus scripts - especialmente se alguns desses computadores não são seus próprios.
  2. O PowerShell não permite acesso externo. execução de script por padrão. A configuração ExecutionPolicy no PowerShell impede a execução de scripts externos por padrão em todas as versões do Windows. Em algumas versões do Windows, o padrão não permite a execução de scripts. Mostramos a você como alterar essa configuração em Como permitir a execução de scripts do PowerShell no Windows 7. No entanto, isso também é algo que você não deseja fazer em qualquer computador.
  3. Alguns scripts do PowerShell não funcionam sem Permissões de administrador. Mesmo executando com uma conta de nível de administrador, você ainda precisa passar pelo Controle de Conta de Usuário (UAC) para executar determinadas ações. Nós não queremos desabilitar isso, mas ainda é bom quando podemos tornar isso um pouco mais fácil de lidar.
  4. Alguns usuários podem ter personalizado ambientes PowerShell.
    Você provavelmente não encontrará isso com freqüência, mas Quando você faz isso, pode tornar a execução e a solução de problemas de seus scripts um pouco frustrantes. Felizmente, podemos contornar isso sem fazer nenhuma alteração permanente também.

Etapa 1: Clique duas vezes para executar.

Vamos começar abordando o primeiro problema - associações de arquivo .PS1. Você não pode clicar duas vezes para executar arquivos .PS1, mas pode executar um arquivo .BAT dessa maneira. Então, vamos escrever um arquivo de lote para chamar o script PowerShell da linha de comando para nós.

Assim, não precisamos reescrever o arquivo de lote para cada script, ou toda vez que movemos um script, ele fará uso de uma variável de auto-referência para construir o caminho do arquivo para o script do PowerShell. Para que isso funcione, o arquivo de lote precisará ser colocado na mesma pasta do script do PowerShell e ter o mesmo nome de arquivo. Portanto, se o script do PowerShell for chamado de “MyScript.ps1”, você deverá nomear o arquivo de lote “MyScript.bat” e certificar-se de que ele esteja na mesma pasta. Em seguida, coloque essas linhas no script em lotes:

@ ECHO OFF PowerShell.exe -Command "& '% ~ dpn0.ps1'" PAUSE

Se não fosse pelas outras restrições de segurança em vigor, isso realmente é tudo o que é preciso para executar um script do PowerShell a partir de um arquivo em lotes. Na verdade, a primeira e a última linha são principalmente apenas uma questão de preferência - é a segunda linha que realmente está fazendo o trabalho. Aqui está a divisão:

@ECHO OFF desativa o eco de comando. Isso apenas impede que seus outros comandos sejam exibidos na tela quando o arquivo em lote é executado. Essa linha é ocultada pelo uso do símbolo (@) na frente dela.

PowerShell.exe -Command “& '% ~ dpn0.ps1'” na verdade executa o script do PowerShell. O PowerShell.exe pode, é claro, ser chamado de qualquer janela CMD ou arquivo em lotes para iniciar o PowerShell em um console simples como o usual. Você também pode usá-lo para executar comandos diretamente de um arquivo de lote, incluindo o parâmetro -Command e argumentos apropriados. A maneira como isso é usado para direcionar nosso arquivo .PS1 é com a variável especial% ~ dpn0. Executar de um arquivo em lotes,% ~ dpn0 avalia a letra da unidade, caminho da pasta e nome do arquivo (sem extensão) do arquivo em lotes. Como o arquivo em lotes e o script do PowerShell estarão na mesma pasta e terão o mesmo nome,% ~ dpn0.ps1 será convertido no caminho completo do arquivo do script do PowerShell.

PAUSA apenas pausa a execução em lote e aguarda a entrada do usuário. Isso geralmente é útil para ter no final de seus arquivos em lotes, para que você tenha uma chance de revisar qualquer saída de comando antes que a janela desapareça. À medida que passamos pelo teste de cada etapa, a utilidade disso se tornará mais óbvia.

Assim, o arquivo de lote básico é configurado. Para fins de demonstração, esse arquivo é salvo como “D: Script Lab MyScript.bat” e há um “MyScript.ps1” na mesma pasta. Vamos ver o que acontece quando clicamos duas vezes em MyScript.bat.

Obviamente, o script do PowerShell não foi executado, mas isso é de se esperar - afinal, só abordamos o primeiro dos nossos quatro problemas. No entanto, há alguns bits importantes demonstrados aqui:

  1. O título da janela mostra que o script em lotes lançou o PowerShell com êxito.
  2. A primeira linha de saída mostra que um perfil personalizado do PowerShell está em uso. Este é o problema potencial nº 4, listado acima.
  3. A mensagem de erro demonstra as restrições da ExecutionPolicy em vigor. Esse é o nosso problema número 2.
  4. A parte sublinhada da mensagem de erro (que é feita originalmente pela saída de erro do PowerShell) mostra que o script em lote estava direcionando corretamente o script PowerShell pretendido (D: Script Lab MyScript.ps1). Então, pelo menos sabemos que muito está funcionando corretamente.

O perfil, neste caso, é um script de uma linha simples usado para esta demonstração para gerar saída sempre que o perfil estiver ativo. Você pode personalizar seu próprio perfil do PowerShell para fazer isso também, se quiser testar esses scripts sozinho. Basta adicionar a seguinte linha ao seu script de perfil:

Perfil Custom PowerShell de saída de gravação 'em vigor!'

A ExecutionPolicy no sistema de teste aqui está definida como RemoteSigned. Isso permite a execução de scripts criados localmente (como o script de perfil), bloqueando scripts de fontes externas, a menos que sejam assinados por uma autoridade confiável. Para fins de demonstração, o comando a seguir foi usado para sinalizar MyScript.ps1 como sendo de uma fonte externa:

Add-Content -Path 'D:  Script Lab  MyScript.ps1' -Value "[ZoneTransfer] 'nZoneId = 3 "-Stream 'Zone.Identifier'

Isso define o fluxo de dados alternativo do Zone.Identifier em MyScript.ps1 para que o Windows pense que o arquivo veio da Internet. Ele pode ser facilmente revertido com o seguinte comando:

Clear-Content -Path 'D:  Script Lab  MyScript.ps1' -Stream 'Zone.Identifier'

Etapa 2: contornando a ExecutionPolicy.

Obtendo em torno da configuração ExecutionPolicy, do CMD ou de um script em lote, é realmente muito fácil. Apenas modificamos a segunda linha do script para adicionar mais um parâmetro ao comando PowerShell.exe.

PowerShell.exe -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'"

O parâmetro -ExecutionPolicy pode pode ser usado para modificar a ExecutionPolicy que é usada quando você gera uma nova sessão do PowerShell. Isso não persistirá além dessa sessão, para que possamos executar o PowerShell desta forma sempre que precisarmos, sem enfraquecer a postura geral de segurança do sistema. Agora que corrigimos isso, vamos fazer outra:

Agora que o script foi executado corretamente, podemos ver o que ele realmente faz. Está nos informando que estamos executando o script como um usuário limitado. Na verdade, o script está sendo executado por uma conta com permissões de Administrador, mas o Controle de Conta de Usuário está atrapalhando. Embora os detalhes de como o script está verificando o acesso de Administrador estejam além do escopo deste artigo, aqui está o código que está sendo usado para demonstração:

if (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity] :: GetCurrent ()). IsInRole ([Security.Principal.WindowsBuiltInRole] "Administrador")) {Write-Output 'em execução como administrador!'} Else {Write-Output 'em execução limitada!'} Pause

Você também notará que agora há duas operações de "Pausa" na saída do script - uma do script do PowerShell e uma do arquivo de lote. A razão para isso será mais aparente na próxima etapa.

Etapa 3: Obtendo acesso de Administrador

Se o seu script não executar nenhum comando que exija elevação e você tiver certeza de que não terá Para se preocupar com os perfis personalizados de qualquer pessoa, você pode pular o resto disso. Se você estiver executando alguns cmdlets de nível de administrador, precisará dessa peça.

Infelizmente, não há como acionar o UAC para elevação a partir de um arquivo em lotes ou sessão CMD. No entanto, o PowerShell nos permite fazer isso com o Start-Process. Quando usado com “-Verb RunAs” em seus argumentos, o Start-Process tentará iniciar um aplicativo com permissões de Administrador. Se a sessão do PowerShell ainda não estiver elevada, isso acionará um prompt do UAC. Para usar isso do arquivo em lote para iniciar nosso script, acabaremos gerando dois processos do PowerShell - um para disparar o Start-Process e outro, iniciado pelo Start-Process, para executar o script. A segunda linha do arquivo de lote precisa ser alterada para:

PowerShell.exe -Command "& {Iniciar-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -File" "% ~ dpn0.ps1" "- Verb RunAs} "

Quando o arquivo de lote é executado, a primeira linha de saída que veremos é do script de perfil do PowerShell. Em seguida, haverá um prompt do UAC quando o Start-Process tentar iniciar o MyScript.ps1.

Depois de clicar no prompt do UAC, uma nova instância do PowerShell será gerada. Como esta é uma nova instância, é claro, veremos novamente o aviso do script de perfil. Então, o MyScript.ps1 é executado e vemos que estamos de fato em uma sessão elevada.

E também há a razão pela qual temos duas pausas aqui. Se não fosse pelo script do PowerShell, nunca veríamos a saída do script - a janela do PowerShell simplesmente apareceria e desapareceria assim que o script fosse executado. E sem a pausa no arquivo de lote, não poderíamos ver se havia algum erro ao iniciar o PowerShell.

Etapa 4: contornando os perfis personalizados do PowerShell.

Vamos nos livrar dessa situação desagradável. aviso de perfil personalizado agora, vamos? Aqui, dificilmente é um incômodo, mas se o perfil do PowerShell de um usuário alterar configurações, variáveis ​​ou funções padrão de maneiras que você pode não ter previsto com seu script, elas podem ser realmente problemáticas. É muito mais simples executar o script sem o perfil, para que você não precise se preocupar com isso. Para fazer isso, só precisamos alterar a segunda linha do arquivo de lote mais uma vez:

PowerShell.exe -NoProfile -Command "& {Iniciar-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File" "% ~ dpn0.ps1" "'-Verb RunAs}"

A adição do parâmetro -NoProfile às duas instâncias do PowerShell que são iniciadas pelo script significa que o script do perfil do usuário será completamente ignorado nas duas etapas e no nosso script do PowerShell será executado em um ambiente padrão razoavelmente previsível. Aqui, você pode ver que não há nenhum aviso de perfil personalizado em qualquer um dos shells gerados.

Se você não precisar de direitos de administrador no script do PowerShell e tiver ignorado a Etapa 3, você pode fazer sem a segunda instância do PowerShell e a segunda linha do arquivo em lotes deve ter a seguinte aparência:

PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'"

A saída ficará assim:

( Obviamente, para scripts que não são de administrador, você também poderia fazer uma pausa no fim do script no script do PowerShell, já que tudo é capturado na mesma janela do console e seria mantido ali pela pausa no final do script. arquivo em lote mesmo assim.)

Arquivos em lote concluídos.

Dependendo se você precisa ou não de permissões de Administrador para o script do PowerShell (e você realmente não deve solicitá-las se não o tiver) o arquivo de lote final deve aparecer como um dos dois abaixo.

Sem acesso de administrador:

@ ECHO OFF PowerShell.exe -NoProfile -ExecutionPoli Bypass -Command "& '% ~ dpn0.ps1'" PAUSE

Com acesso de administrador:

@ ECHO OFF PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile - ExecutionPolicy Bypass -File "% ~ dpn0.ps1 " -Verb RunAs} "PAUSE

Lembre-se de colocar o arquivo em lotes na mesma pasta que o script do PowerShell para o qual deseja usá-lo e nomeie-o . Em seguida, não importa em qual sistema você leva esses arquivos, você poderá executar o script do PowerShell sem ter que se preocupar com as configurações de segurança do sistema. Você certamente poderia fazer essas alterações manualmente todas as vezes, mas isso poupa esse problema e você não terá que se preocupar em reverter as alterações posteriormente.


Referências:

  • Executando scripts do PowerShell a partir de um arquivo em lotes - Blog de Programação do Daniel Schroeder
  • Verificando permissões de Administrador no PowerShell - Ei, Equipe de Scripts! Blog


Você pode converter um adaptador sem fio interno em um dongle?

Você pode converter um adaptador sem fio interno em um dongle?

Se você odeia ver boas peças eletrônicas serem desperdiçadas, é provável que procure maneiras de incorporá-las a outros dispositivos ou tê-las como acessórios de algum tipo. Com isso em mente, a postagem de perguntas e respostas do SuperUser de hoje oferece alguns conselhos úteis para um leitor curioso.

(how-to)

Você precisa usar um limpador de driver ao atualizar drivers?

Você precisa usar um limpador de driver ao atualizar drivers?

Alguns nerds usam “limpadores de drivers” ao atualizar seus drivers - geralmente drivers gráficos - para garantir que o driver antigo foi completamente desinstalado e Nenhum arquivo restante ficará em conflito com o novo driver. Mas isso é necessário? Se você já usou um limpador de motoristas, provavelmente foi há alguns anos.

(how-to)