Como configurar o Windows para trabalhar com scripts do PowerShell com mais facilidade
O Windows e o PowerShell têm recursos de segurança incorporados e configurações padrão destinadas a impedir que os usuários finais iniciem scripts de forma acidental no decorrer de suas atividades diárias. No entanto, se as suas atividades diárias rotineiramente envolvem escrever e executar seus próprios scripts do PowerShell, isso pode ser mais um incômodo do que um benefício. Aqui, mostraremos como contornar esses recursos sem comprometer totalmente a segurança.
Como e por que o Windows e o PowerShell impedem a execução de scripts.
O PowerShell é efetivamente o shell de comando e a linguagem de script destinada a substituir os scripts CMD e em lote nos sistemas Windows. Como tal, um script do PowerShell pode ser configurado para fazer qualquer coisa que você possa fazer manualmente a partir da linha de comando. Isso equivale a tornar praticamente possível qualquer alteração no seu sistema, até as restrições estabelecidas na sua conta de usuário. Portanto, se você pudesse clicar duas vezes em um script do PowerShell e executá-lo com privilégios totais de Administrador, uma simples anotação como essa poderia realmente arruinar seu dia:
Get-ChildItem "$ env: SystemDrive \" -Recurse -ErrorAction SilentlyContinue | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue
NÃO execute o comando acima!
Isso simplesmente passa pelo sistema de arquivos e apaga tudo o que puder. Curiosamente, isso pode não tornar o sistema inoperável o mais rápido possível - mesmo quando executado em uma sessão elevada. Mas se alguém ligar para você depois de executar este script, porque de repente eles não conseguem encontrar seus arquivos ou executar alguns programas, “desligá-lo e ligá-lo novamente” provavelmente os levará para o Windows Startup Repair, onde serão informados de que nada que possa ser feito para corrigir o problema. O que poderia ser pior é que, em vez de obter um script que apenas destrói o sistema de arquivos, seu amigo pode ser enganado e executar um que baixa e instale um keylogger ou um serviço de acesso remoto. Então, em vez de fazer perguntas sobre o Reparo de Inicialização, eles podem acabar fazendo à polícia algumas perguntas sobre fraude bancária.!
Até agora, deveria ser óbvio por que certas coisas são necessárias para proteger os usuários finais de si mesmos, por assim dizer. Mas usuários avançados, administradores de sistemas e outros geeks são geralmente (embora existam exceções) um pouco mais cautelosos com essas ameaças, sabendo como identificá-los e evitá-los facilmente, e apenas querem continuar seu trabalho. Para fazer isso, eles terão que desativar ou contornar alguns bloqueios de estrada:
- O PowerShell não permite a execução de scripts externos 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, mas abordaremos aqui alguns níveis também. - O PowerShell não está associado à extensão de arquivo .PS1 por padrão.
Nós trouxemos isso inicialmente em nossa série PowerShell Geek School. O Windows define a ação padrão para arquivos .PS1 para abri-los no Bloco de Notas, em vez de enviá-los para o interpretador de comandos do PowerShell. Isso evita diretamente a execução acidental de scripts mal-intencionados quando eles são clicados duas vezes. - 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. Para ferramentas de linha de comando, isso pode ser um pouco incômodo para dizer o mínimo. Nós não queremos desabilitar o UAC, mas ainda é bom quando podemos tornar um pouco mais fácil lidar com.
Esses mesmos problemas aparecem em Como usar um arquivo em lotes para facilitar a execução de scripts do PowerShell, onde orientamos você ao escrever um arquivo em lotes para contorná-los temporariamente. Agora, vamos mostrar a você como configurar seu sistema com uma solução de longo prazo. Lembre-se de que você geralmente não deve fazer essas alterações em sistemas que não são usados exclusivamente por você. Caso contrário, você estará colocando outros usuários em maior risco de ter os mesmos problemas que esses recursos visam evitar.
Alterando a associação de arquivo .PS1.
O primeiro, e talvez principal, aborrecimento para se locomover é a associação padrão para arquivos .PS1. Associar esses arquivos a algo diferente de PowerShell.exe faz sentido para impedir a execução acidental de scripts indesejáveis. Mas, considerando que o PowerShell vem com um Integrated Scripting Environment (ISE) que é especificamente projetado para edição de scripts do PowerShell, por que queremos abrir arquivos .PS1 no Bloco de Notas por padrão? Mesmo que você não esteja pronto para mudar totalmente para a funcionalidade de clicar duas vezes para executar, provavelmente desejará ajustar essas configurações.
Você pode alterar a associação de arquivo .PS1 para qualquer programa que desejar com o painel de controle Programas padrão, mas cavar diretamente no Registro dará a você um pouco mais de controle sobre exatamente como os arquivos serão abertos. Isso também permite definir ou alterar opções adicionais que estão disponíveis no menu de contexto para arquivos .PS1. Não se esqueça de fazer um backup do registro antes de fazer isso!
As configurações do registro que controlam como os scripts do PowerShell são abertos são armazenadas no seguinte local:
HKEY_CLASSES_ROOT \ Microsoft.PowerShellScript.1 \ Shell
Para explorar essas configurações antes de alterá-las, dê uma olhada nessa chave e em suas sub-chaves com o Regedit. A chave Shell deve ter apenas um valor, “(Padrão)”, que é definido como “Abrir”. Este é um ponteiro para a ação padrão para clicar duas vezes no arquivo, que veremos nas subchaves.
Expanda a chave Shell e você verá três sub-chaves. Cada uma delas representa uma ação que você pode executar, específica dos scripts do PowerShell.
Você pode expandir cada chave para explorar os valores, mas eles basicamente se igualam aos seguintes padrões:
- 0 - Executar com o PowerShell. "Executar com o PowerShell" é, na verdade, o nome de uma opção já no menu de contexto dos scripts do PowerShell. O texto é retirado de outro local, em vez de usar o nome da chave, como os outros. E ainda não é a ação padrão de clique duplo.
- Editar - Abrir no PowerShell ISE. Isso faz muito mais sentido do que o Bloco de Notas, mas você ainda precisa clicar com o botão direito do mouse no arquivo .PS1 para fazer isso por padrão.
- Abrir - Abra no Bloco de Notas. Observe que esse nome de chave também é a sequência armazenada no valor “(Padrão)” da chave Shell. Isso significa que clicar duas vezes no arquivo "abrirá" e que a ação é normalmente definida para usar o bloco de notas.
Se você quiser manter as strings de comando pré-compiladas já disponíveis, basta alterar o valor “(Padrão)” na chave Shell para corresponder ao nome da chave que corresponde ao que você deseja que um clique duplo faça. Isso pode ser feito facilmente a partir do Regedit ou você pode usar as lições aprendidas em nosso tutorial sobre como explorar o registro com o PowerShell (além de um pequeno ajuste do PSDrive) para começar a criar um script reutilizável que possa configurar seus sistemas para você. Os comandos abaixo devem ser executados a partir de uma sessão elevada do PowerShell, semelhante à execução do CMD como Administrador.
Primeiro, você desejará configurar um PSDrive para HKEY_CLASSES_ROOT, já que isso não está configurado por padrão. O comando para isso é:
Registro HKCR do Novo PSDrive HKEY_CLASSES_ROOT
Agora você pode navegar e editar chaves e valores de registro em HKEY_CLASSES_ROOT como faria nos PSDrives normais de HKCU e HKLM.
Para configurar o clique duplo para iniciar os scripts do PowerShell diretamente:
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell '(padrão)' 0
Para configurar o clique duplo para abrir scripts do PowerShell no ISE do PowerShell:
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell '(padrão) "Editar"
Para restaurar o valor padrão (conjuntos, clique duas vezes para abrir scripts do PowerShell no Bloco de Notas):
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell '(padrão) "Abrir'
Isso é apenas o básico de alterar a ação padrão de clique duplo. Entraremos em mais detalhes sobre como personalizar os scripts do PowerShell quando eles forem abertos no PowerShell a partir do Explorer na próxima seção. Tenha em mente que o escopo impede que os PSDrives persistam nas sessões. Assim, você provavelmente desejará incluir a linha New-PSDrive no início de qualquer script de configuração criado para essa finalidade ou adicioná-lo ao seu perfil do PowerShell. Caso contrário, você precisará executar esse bit manualmente antes de tentar fazer alterações dessa maneira.
Alterando a configuração de ExecutionPolicy do PowerShell.
A ExecutionPolicy do PowerShell é outra camada de proteção contra a execução de scripts mal-intencionados. Existem várias opções para isso, e algumas maneiras diferentes podem ser definidas. Do mais ao menos seguro, as opções disponíveis são:
- Restrito - Nenhum script pode ser executado. (Configuração padrão para a maioria dos sistemas.) Isso impedirá que seu script de perfil seja executado.
- AllSigned - Todos os scripts devem ser assinados digitalmente por um editor confiável para serem executados sem avisar o usuário. Scripts assinados por editores explicitamente definidos como não confiáveis ou scripts não assinados digitalmente não serão executados. O PowerShell solicitará ao usuário a confirmação se um script for assinado por um editor ainda não definido como confiável ou não confiável. Se você não assinou digitalmente seu script de perfil e estabeleceu confiança nessa assinatura, ele não poderá ser executado. Tenha cuidado com os editores nos quais você confia, pois você ainda pode acabar executando scripts maliciosos se confiar no errado.
- RemoteSigned - Para scripts baixados da Internet, isso é efetivamente o mesmo que “AllSigned”. No entanto, scripts criados localmente ou importados de fontes diferentes da Internet podem ser executados sem nenhum aviso de confirmação. Aqui, você também precisa ter cuidado com as assinaturas digitais nas quais confia, mas até mesmo ter mais cuidado com os scripts não assinados que escolhe para executar. Este é o nível mais alto de segurança sob o qual você pode ter um script de perfil de trabalho sem ter que assiná-lo digitalmente.
- Irrestrito - Todos os scripts podem ser executados, mas um prompt de confirmação será necessário para scripts da Internet. Deste ponto em diante, é totalmente sua responsabilidade evitar a execução de scripts não confiáveis.
- Bypass - Tudo funciona sem um aviso. Tenha cuidado com este.
- Indefinido - Nenhuma política é definida no escopo atual. Isso é usado para permitir fallback para políticas definidas em escopos inferiores (mais detalhes abaixo) ou para os padrões do SO.
Como sugerido pela descrição de Undefined, as políticas acima podem ser definidas em um ou mais dos vários escopos. Você pode usar Get-ExecutionPolicy, com o parâmetro -List, para ver todos os escopos e suas configurações atuais.
Os escopos são listados na ordem de precedência, com o escopo definido mais acima substituindo todos os outros. Se nenhuma política for definida, o sistema voltará à configuração padrão (na maioria dos casos, isso é Restrito).
- MachinePolicy representa uma diretiva de grupo em vigor no nível do computador. Isso geralmente é aplicado apenas em um domínio, mas também pode ser feito localmente.
- UserPolicy representa uma Política de Grupo em vigor no usuário. Isso também é normalmente usado apenas em ambientes corporativos.
- Processo é um escopo específico para essa instância do PowerShell. As alterações na política neste escopo não afetarão outros processos do PowerShell em execução e serão ineficazes após essa sessão ser encerrada. Isso pode ser configurado pelo parâmetro -ExecutionPolicy quando o PowerShell é iniciado ou pode ser definido com a sintaxe Set-ExecutionPolicy adequada de dentro da sessão.
- CurrentUser é um escopo configurado no registro local e se aplica à conta de usuário usada para iniciar o PowerShell. Este escopo pode ser modificado com Set-ExecutionPolicy.
- LocalMachine é um escopo configurado no registro local e aplicado a todos os usuários no sistema. Esse é o escopo padrão que é alterado se Set-ExecutionPolicy for executado sem o parâmetro -Scope. Como se aplica a todos os usuários do sistema, ele só pode ser alterado de uma sessão elevada.
Como este artigo trata principalmente de contornar a segurança para facilitar a usabilidade, estamos preocupados apenas com os três escopos inferiores. As configurações MachinePolicy e UserPolicy são realmente úteis somente se você quiser impor uma diretiva restritiva que não seja simplesmente ignorada. Mantendo nossas alterações no nível do Processo ou abaixo, podemos usar facilmente qualquer configuração de política que considerarmos apropriada para uma determinada situação a qualquer momento.
Para manter algum equilíbrio entre segurança e usabilidade, a política mostrada na captura de tela é provavelmente a melhor. Definir a política LocalMachine como Restrita geralmente impede a execução de scripts por qualquer pessoa que não seja você. Claro, isso pode ser ignorado pelos usuários que sabem o que estão fazendo sem muito esforço. Mas isso deve impedir que qualquer usuário não experiente em tecnologia acidentalmente acione algo catastrófico no PowerShell. Ter o CurrentUser (ou seja, você) definido como Irrestrito permite que você execute scripts manualmente a partir da linha de comando, como preferir, mas retenha um lembrete de cautela para os scripts baixados da Internet. A configuração RemoteSigned no nível do processo precisaria ser feita em um atalho para o PowerShell.exe ou (como faremos a seguir) nos valores do Registro que controlam o comportamento dos scripts do PowerShell. Isso permitirá a funcionalidade de clicar duas vezes para executar qualquer script que você escrever, ao mesmo tempo em que criará uma barreira mais forte contra a execução não intencional de scripts (potencialmente mal-intencionados) de fontes externas. Queremos fazer isso aqui, pois é muito mais fácil clicar duas vezes em um script do que geralmente chamá-lo manualmente a partir de uma sessão interativa..
Para definir as políticas CurrentUser e LocalMachine como na captura de tela acima, execute os seguintes comandos em uma sessão elevada do PowerShell:
Set-ExecutionPolicy Restrito Set-ExecutionPolicy Irrestrito -Scope CurrentUser
Para impor a política RemoteSigned em scripts executados a partir do Explorer, teremos que alterar um valor dentro de uma das chaves de registro que estávamos procurando anteriormente. Isso é particularmente importante porque, dependendo da sua versão do PowerShell ou do Windows, a configuração padrão pode ser ignorar todas as configurações de ExecutionPolicy, exceto AllSigned. Para ver qual é a configuração atual do seu computador, você pode executar este comando (certificando-se de que o HKCR PSDrive está mapeado primeiro):
Get-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Comando | Selecionar Objeto '(Padrão)'
Sua configuração padrão provavelmente será uma das duas sequências a seguir, ou algo bastante semelhante:
(Visto no Windows 7 SP1 x64, com o PowerShell 2.0)
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-arquivo" "% 1"
(Visto no Windows 8.1 x64, com o PowerShell 4.0)
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-Command" "if ((Get-ExecutionPolicy) -ne 'AllSigned') Ignorar Processo Set-ExecutionPolicy -Scope; & '% 1 '"
O primeiro não é tão ruim, pois tudo o que ele faz é executar o script sob as configurações existentes da ExecutionPolicy. Isso poderia ser melhor, impondo restrições mais rígidas para uma ação mais propensa a acidentes, mas isso não era originalmente planejado para ser ativado em um clique duplo, e a política padrão é geralmente restrita, afinal. A segunda opção, no entanto, é um desvio completo de qualquer Política de Execução que você possa ter no lugar - mesmo restrito. Como o desvio será aplicado no escopo do Processo, ele afeta apenas as sessões que são iniciadas quando os scripts são executados no Explorer. No entanto, isso significa que você pode acabar iniciando scripts que, de outra forma, esperaria (e desejaria) que sua política proibisse.
Para definir a ExecutionPolicy de nível de processo para scripts iniciados no Explorer, de acordo com a captura de tela acima, você precisará modificar o mesmo valor de registro que acabamos de consultar. Você pode fazê-lo manualmente no Regedit, alterando-o para isso:
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-ExecutionPolicy" "RemoteSigned" "-file" "% 1"
Você também pode alterar a configuração de dentro do PowerShell, se preferir. Lembre-se de fazer isso em uma sessão elevada, com o HKCR PSDrive mapeado.
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Comando '(Padrão) "" C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe "" -ExecutionPolicy "" RemoteSigned "" -file "" % 1 "'
Executar scripts do PowerShell como administrador.
Assim como é uma má idéia desabilitar o UAC por completo, também é uma prática de segurança incorreta executar scripts ou programas com privilégios elevados, a menos que você realmente precise deles para executar operações que exijam acesso de Administrador. Portanto, não é recomendável criar o prompt do UAC na ação padrão dos scripts do PowerShell. No entanto, podemos adicionar uma nova opção de menu de contexto para permitir a execução fácil de scripts em sessões elevadas quando necessário. Isso é semelhante ao método usado para adicionar "Abrir com o bloco de notas" ao menu de contexto de todos os arquivos, mas aqui só vamos direcionar os scripts do PowerShell. Também vamos utilizar algumas técnicas usadas no artigo anterior, em que usamos um arquivo em lotes em vez de hacks de registro para lançar nosso script do PowerShell.
Para fazer isso no Regedit, volte para a chave Shell, em:
HKEY_CLASSES_ROOT \ Microsoft.PowerShellScript.1 \ Shell
Lá, crie uma nova subchave. Chame de "Executar com o PowerShell (Admin)". Abaixo disso, crie outra subchave chamada "Comando". Em seguida, defina o valor “(Padrão)” em Comando para isto:
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-Command" "" & Iniciar-Process PowerShell.exe -ArgumentList '-ExecutionPolicy RemoteSigned -File \ "% 1 \"' -Verb RunAs "
Fazer o mesmo no PowerShell, na verdade, precisará de três linhas neste momento. Um para cada nova chave e um para definir o valor “(Padrão)” para Comando. Não esqueça a elevação e o mapeamento HKCR.
New-Item 'HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Executar com o PowerShell (Admin)' Novo Item 'HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Executar com o PowerShell (Admin) \ Comando' Set-ItemProperty ' HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Executar com o PowerShell (Admin) \ Comando "(Padrão)" "C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-Command" "" & Iniciar processo PowerShell.exe -ArgumentList "-ExecutionPolicy RemoteSigned -File \"% 1 \ "" - Verb RunAs "'
Além disso, preste muita atenção às diferenças entre a string que está sendo inserida no PowerShell e o valor real que está sendo inserido no Registro. Particularmente, temos que agrupar a coisa toda entre aspas simples e dobrar as aspas simples internas, para evitar erros na análise de comandos.
Agora você deve ter uma nova entrada de menu de contexto para scripts do PowerShell, chamada "Executar com o PowerShell (Admin)".
A nova opção gerará duas instâncias consecutivas do PowerShell. O primeiro é apenas um ativador para o segundo, que usa Start-Process com o parâmetro “-Verb RunAs” para solicitar elevação para a nova sessão. A partir daí, seu script deve ser executado com privilégios de administrador depois de clicar no prompt do UAC.
Toques finais.
Há mais alguns ajustes que podem ajudar a tornar a vida ainda mais fácil. Por um lado, que tal se livrar completamente da função Notepad? Simplesmente copie o valor “(Padrão)” da tecla Comando em Editar (abaixo), para o mesmo local em Abrir.
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell_ise.exe" "% 1"
Ou você pode usar este pouco de PowerShell (com Admin e HKCR, é claro):
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Open \ Comando '(Padrão) "" C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell_ise.exe ""% 1 "'
Um aborrecimento menor é o hábito do console de desaparecer quando um script é concluído. Quando isso acontece, não temos nenhuma chance de revisar a saída do script em busca de erros ou outras informações úteis. Isso pode ser resolvido colocando uma pausa no final de cada um dos seus scripts, é claro. Como alternativa, podemos modificar os valores “(Padrão)” para as nossas teclas de comando para incluir o parâmetro “-NoExit”. Abaixo estão os valores modificados.
(Sem acesso de administrador)
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-NoExit" "-ExecutionPolicy" "RemoteSigned" "-file" "% 1"
(Com acesso de administrador)
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-Command" "" & Iniciar-Processo PowerShell.exe -ArgumentList '-NoExit -ExecutionPolicy RemoteSigned -File \ "% 1 \"' - Verbo RunAs "
E, claro, também daremos a você os comandos do PowerShell. Último lembrete: elevação e HKCR!
(Não administrador)
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Comando '(Padrão) "" C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe "" -NoExit "" -ExecutionPolicy "" RemoteSigned "" -file ""% 1 "'
(Admin)
Set-ItemProperty 'HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Executar com o PowerShell (Admin) \ Comando "(Padrão)" "C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-Command" "" & Start-Process PowerShell.exe -ArgumentList "-NoExit -ExecutionPolicy RemoteSigned -File \"% 1 \ "" - Verb RunAs "'
Tomando um giro.
Para testar isso, vamos usar um script que pode nos mostrar as configurações de ExecutionPolicy e se o script foi iniciado com permissões de administrador. O script será chamado “MyScript.ps1” e será armazenado em “D: \ Script Lab” em nosso sistema de amostra. O código está abaixo, para referência.
if (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity] :: GetCurrent ()). IsInRole ([Security.Principal.WindowsBuiltInRole] "Administrador")) Write-Output 'em execução como administrador!' else Write-Output 'Running Limited!' Get-ExecutionPolicy -List
Usando a ação "Executar com o PowerShell":
Usando a ação “Executar com o PowerShell (Admin)”, depois de clicar no UAC:
Para demonstrar a ExecutionPolicy em ação no escopo do Processo, podemos fazer com que o Windows pense que o arquivo veio da Internet com esse código do PowerShell:
Add-Content -Path 'D: \ Script Lab \ MyScript.ps1' -Value "[ZoneTransfer] 'nZoneId = 3" -Stream' Zone.Identifier '
Felizmente, nós tivemos -NoExit habilitado. Caso contrário, esse erro teria apenas piscado, e nós não saberíamos!
O Zone.Identifier pode ser removido com isto:
Clear-Content -Path 'D: \ Script Lab \ MyScript.ps1' -Stream 'Zone.Identifier'
Referências Úteis:
- Executando scripts do PowerShell a partir de um arquivo em lotes - Blog de programação de Daniel Schroeder
- Verificando permissões de administrador no PowerShell - Ei, Equipe de Scripts! Blog