2010-12-08 16 views
22

J'ai un gros script batch qui définit un tas de variables d'environnement. Je veux appeler ce script de lot à partir de powershell, de cette façon je peux obtenir les avantages de la variable d'enviorment définie par mon script et powershell.Comment appeler un script batch depuis Powershell?

Répondre

12

L'idée vient de ce blog: Nothing solves everything – PowerShell and other technologies

Voici ma version de ce script. Il appelle un fichier batch (ou toute commande native ) et propage son environnement:


MISE À JOUR: L'amélioration et la version 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" 
} 

post-scriptum Voici la proposition d'ajouter une capacité similaire à PowerShell: Extend dot sourcing concept to cmd files

+1

Vous pouvez utiliser simplement '$ Command> nul 2> & 1 && set' juste au cas où' $ Command' a un code de sortie différent de zéro mais change quand même l'environnement. – Joey

+0

La version "améliorée et mieux testée" ne fonctionnait pas pour moi, mais copier copier le script de cette réponse a fait. –

+0

Merci pour l'alarme. Pouvez-vous créer un problème [ici] (https://github.com/nightroman/PowerShelf/issues) et décrire votre cas d'utilisation? –

0

Vous pouvez exécuter un script batch à partir de Powershell simplement en mettant son nom, mais cela ne vous aidera pas. Les variables d'environnement définies dans le script de traitement par lots ne seront visibles qu'à partir de ce lot et tout ce qui est exécuté par lots. Une fois que le contrôle revient à Powershell, les variables d'environnement ont disparu. Vous pouvez faire exécuter le script batch set à la fin, puis analyser sa sortie dans vos variables d'environnement PSH, cependant.

2

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 sans souci:

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 courte, ne retourne que string):

PS> $env:path 
c:\dev\CollabNet\Subversion Client;C:\Windows\system32;... 

Vous pouvez modifier le chemin de l'environnement comme celui-ci:

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') 
21

Si vous prenez le PowerShell Community Extensions, il y a une commande Invoke-batchfile en elle qui exécute le fichier de commandes, mais plus important encore, il conserve toutes les modifications variables d'environnement faites par le lot file 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. 
+0

Assez cool, je dois regarder dans le src :) – stej

+0

Remarques à soi, comme ci-dessous, 1.Pour installer à partir du fichier zip sur codeplex, à droite -clic et un bouton modal, "débloquer" apparaît; cliquez dessus. 2.Unzip après le déblocage, puis placez le dossier dans l'emplacement de votre module, comme $ PSHome \ Modules. http://stam.blogs.com/8bits/2010/06/installing-powershell-community-extensions.html – AnneTheAgile

Questions connexes