J'ai un gros script de lot qui définit un tas de variables d'environnement. Je veux appeler ce script batch de powershell, afin d’obtenir des avantages des deux variables d’environnement définies par mon script et par powershell.
L'idée vient de ce billet de blog: Rien ne résout tout - PowerShell et d'autres technologies
Voici ma version de ce script. Il appelle un fichier de commandes (ou n’importe quelle commande native) et propage son environnement:
UPDATE: La version améliorée et mieux testée de ce script est ici: Invoke-Environment.ps1
<#
.SYNOPSIS
Invokes a command and imports its environment variables.
.DESCRIPTION
It invokes any cmd Shell command (normally a configuration batch file) and
imports its environment variables to the calling process. Command output is
discarded completely. It fails if the command exit code is not 0. To ignore
the exit code use the 'call' command.
.PARAMETER Command
Any cmd Shell command, normally a configuration batch file.
.EXAMPLE
# Invokes Config.bat in the current directory or the system path
Invoke-Environment Config.bat
.EXAMPLE
# Visual Studio environment: works even if exit code is not 0
Invoke-Environment 'call "%VS100COMNTOOLS%\vsvars32.bat"'
.EXAMPLE
# This command fails if vsvars32.bat exit code is not 0
Invoke-Environment '"%VS100COMNTOOLS%\vsvars32.bat"'
#>
param
(
[Parameter(Mandatory=$true)] [string]
$Command
)
cmd /c "$Command > nul 2>&1 && set" | .{process{
if ($_ -match '^([^=]+)=(.*)') {
[System.Environment]::SetEnvironmentVariable($matches[1], $matches[2])
}
}}
if ($LASTEXITCODE) {
throw "Command '$Command': exit code: $LASTEXITCODE"
}
P.S. Voici la proposition visant à ajouter une capacité similaire à PowerShell: Étendre le concept de source d'approvisionnement aux fichiers cmd
Si vous récupérez le PowerShell Community Extensions , il contient une commande Invoke-BatchFile qui exécute le fichier de commandes, mais plus important encore, il conserve toutes les modifications de variables d'environnement apportées par le fichier de commandes, par exemple:
>Invoke-BatchFile 'C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat'
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
Est-il possible de convertir votre script batch en script PowerShell? Si vous exécutez le fichier bat, il est exécuté dans une session distincte qui ne modifie pas les variables d'environnement de PowerShell.
Vous pouvez travailler avec des variables env très facilement:
PS> Get-ChildItem env:
Name Value
---- -----
ALLUSERSPROFILE C:\ProgramData
APPDATA C:\Users\xyz\AppData\Roaming
CommonProgramFiles C:\Program Files (x86)\Common Files
CommonProgramFiles(x86) C:\Program Files (x86)\Common Files
CommonProgramW6432 C:\Program Files\Common Files
COMPUTERNAME xyz
ComSpec C:\Windows\system32\cmd.exe
DXSDK_DIR D:\prgs\dev\Microsoft DirectX SDK (August 2009)\
FP_NO_Host_CHECK NO
HOMEDRIVE Z:
HOMEPATH \
...
PS> Get-Item env:path
Name Value
---- -----
Path c:\dev\CollabNet\SubversionClient;C:\Windows\system32;...
Ou même (beaucoup plus court, ne renvoie que chaîne):
PS> $env:path
c:\dev\CollabNet\Subversion Client;C:\Windows\system32;...
Vous pouvez changer le chemin de l'environnement comme ceci:
PS> $env:path += ";c:\mydir"
Et vous pouvez même définir des variables d'environnement au niveau de la machine comme ceci:
# fist arg = env variable name, second = value, third = level, available are 'Process', 'User', 'Machine'
PS> [Environment]::SetEnvironmentVariable('test', 'value', 'machine')
Vous pouvez exécuter un script batch à partir de Powershell en mettant simplement son nom, mais cela ne vous aidera pas. Les variables d'environnement définies dans le script de traitement par lots ne seront visibles que depuis ce lot et tout ce que ce dernier exécute . Une fois que le contrôle est revenu dans Powershell, les variables d'environnement ont disparu. Vous pouvez également faire exécuter le script de traitement par lots set
à la fin, puis analyser sa sortie dans vos variables d'environnement PSH.