web-dev-qa-db-fra.com

Comment appeler un script batch depuis Powershell?

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.

23
Invincible

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

12
Roman Kuzmin

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.
21
Keith Hill

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')
2
stej

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.

0
Gabe