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.
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.
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:
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'
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.
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.
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.)
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:
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.
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.