Script PowerShell executa sem erro, mas não cria o arquivo: causa real e solução
Durante a automação de scripts em PowerShell, é comum nos depararmos com situações em que o script executa até o fim, exibe mensagens de sucesso, mas o resultado esperado simplesmente não é gerado.
Foi exatamente esse o problema que enfrentei ao criar um script para concatenar múltiplos arquivos .sql em um único arquivo de migration ("migration.sql").

Este artigo descreve o erro real, por que ele acontece e qual é a forma correta de resolvê-lo.
• The Problem:
O script tinha como objetivo:
- identificar o diretório onde o script estava localizado;
- localizar todos os arquivos
.sql; - concatená-los em um único arquivo
migration.sql.
A lógica estava correta, porém o arquivo final não era criado, mesmo com a mensagem final indicando sucesso.
O trecho crítico do código era este:
$scriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Em seguida, o caminho era usado para criar o arquivo:
$outputFile = Join-Path $scriptDirectory "migration.sql"
O resultado prático:
- o script executava;
- nenhum erro explícito de lógica era apresentado;
- o arquivo
migration.sqlnão existia no final.
• O erro real
O problema não estava em permissões, nem na versão do PowerShell, nem no filesystem.
O erro estava no uso de:
$MyInvocation.MyCommand.Definition
Esse atributo não é confiável para resolver o caminho físico do script em todos os contextos de execução.
Dependendo de como o script é executado (VS Code, PowerShell ISE, execução parcial, dot-sourcing ou chamada por outro script), esse valor pode:
- retornar
$null; - retornar apenas o nome do comando;
- retornar algo que não representa um caminho válido.
Quando isso acontece (após testes):
Split-Pathfalha silenciosamente$scriptDirectoryfica nuloJoin-Pathgera um caminho inválidoTest-Path,New-ItemeOut-Filefalham- O script continua até o final e exibe a mensagem de sucesso
Ou seja: o script falha sem parecer que falhou.
• A solução correta
A correção consistiu em utilizar a variável automática adequada para esse cenário:
$PSScriptRoot
Essa variável:
- aponta sempre para o diretório físico onde o arquivo
.ps1está localizado; - funciona de forma consistente no PowerShell 5.1 e 7+;
- independe da forma como o script é executado.
• Script corrigido (versão final)
A única alteração necessária foi substituir a forma de obter o diretório do script, mantendo toda a estrutura original.

📄 Script original (com erro)

Este era o script inicial. A lógica estava correta, porém a forma de obter o diretório do script causava falhas silenciosas na criação do arquivo final.
• Problema desse código
$MyInvocation.MyCommand.Definitionpode retornar$nullou um valor inválido dependendo do contexto de execução.- Isso fazia com que
$scriptDirectoryficasse incorreto. - O script terminava sem erros aparentes, mas o arquivo
migration.sqlnão era criado.
• Resumo da correção
- ❌ Antes: uso de
$MyInvocation.MyCommand.Definition(instável) - ✅ Depois: uso de
$PSScriptRoot(estável e recomendado) - 🔧 Nenhuma mudança na lógica principal
- 📁 Arquivo final criado corretamente em todos os cenários de execução



