web-dev-qa-db-fra.com

Appelez le script PowerShell PS1 à partir d'un autre script PS1 dans Powershell ISE

Je souhaite exécuter un appel pour un script myScript1.ps1 dans un second script myScript2.ps1 dans Powershell ISE.

Le code suivant dans MyScript2.ps1, fonctionne bien dans l'administration Powershell, mais ne fonctionne pas dans PowerShell ISE:

#Call myScript1 from myScript2
invoke-expression -Command .\myScript1.ps1

J'obtiens l'erreur suivante lorsque j'exécute MyScript2.ps1 à partir de PowerShell ISE:

Le terme '.\MyScript1.ps1' n'est pas reconnu en tant que nom d'une applet de commande, fonction, fichier de script ou programme utilisable. Vérifiez l'orthographe du nom ou, si un chemin a été inclus, vérifiez que le chemin est correct et réessayez.

99
Nicola Celiento

Afin de trouver l'emplacement d'un script, utilisez Split-Path $MyInvocation.MyCommand.Path (assurez-vous de l'utiliser dans le contexte du script).

La raison pour laquelle vous devriez utiliser cela et pas autre chose peut être illustrée avec cet exemple de script.

## ScriptTest.ps1
Write-Host "InvocationName:" $MyInvocation.InvocationName
Write-Host "Path:" $MyInvocation.MyCommand.Path

Voici quelques résultats.

 PS C:\Utilisateurs\JasonAr>.\ScriptTest.ps1 
 InvocationName:.\ScriptTest.ps1 
 Chemin: C:\Utilisateurs\JasonAr\ScriptTest.ps1 
.. PS.\Users\JasonAr>. .\ScriptTest.ps1 
 InvocationName: ..
 Chemin: C:\Utilisateurs\JasonAr\ScriptTest.ps1 

 PS C:\Utilisateurs\JasonAr> & ".\ScriptTest.ps1". .InvocationName: & 
 Path: C:\Utilisateurs\JasonAr\ScriptTest.ps1 

Dans PowerShell 3.0 et les versions ultérieures, vous pouvez utiliser la variable automatique $PSScriptRoot:

## ScriptTest.ps1
Write-Host "Script:" $PSCommandPath
Write-Host "Path:" $PSScriptRoot
 PS C:\Utilisateurs\jarcher>.\ScriptTest.ps1 
 Script: C:\Utilisateurs\jarcher\ScriptTest.ps1 
 Chemin: C:\Utilisateurs\jarcher 
68
JasonMArcher

Le chemin actuel de MyScript1.ps1 n’est pas le même que myScript2.ps1. Vous pouvez obtenir le chemin du dossier de MyScript2.ps1 et le concaténer dans MyScript1.ps1, puis l'exécuter. Les deux scripts doivent être au même endroit.

## MyScript2.ps1 ##
$ScriptPath = Split-Path $MyInvocation.InvocationName
& "$ScriptPath\MyScript1.ps1"
30
Shay Levy

Une solution en ligne:

& ((Split-Path $MyInvocation.InvocationName) + "\MyScript1.ps1")
16
noelicus

J'appelle myScript1.ps1 à partir de myScript2.ps1.

En supposant que les deux scripts se trouvent au même emplacement, commencez par obtenir l'emplacement du script à l'aide de la commande suivante:

$PSScriptRoot

Et, ensuite, ajoutez le nom du script que vous voulez appeler comme ceci:

& "$PSScriptRoot\myScript1.ps1"

Cela devrait marcher.

10
Srijani Ghosh

Ceci est juste des informations supplémentaires pour answersin afin de passer l'argument dans un autre fichier 

Où vous attendez une dispute

NomImage.ps1

Param(
    [Parameter( Mandatory = $true)]
    $printName = "Joe"    
)


Write-Host $printName

Comment appeler le fichier  

Param(
    [Parameter( Mandatory = $false)]
    $name = "Joe"    
)


& ((Split-Path $MyInvocation.InvocationName) + "\PrintName.ps1") -printName $name

Si vous ne fournissez aucune entrée, la valeur par défaut sera "Joe" et sera transmise comme argument dans l'argument printName dans PrintName.ps1 fichier , Qui à son tour imprimera le "Joe". chaîne

4
cpoDesign

Vous avez peut-être déjà trouvé la réponse, mais voici ce que je fais. 

Je place généralement cette ligne au début de mes scripts d'installation:

if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).  

Ensuite, je peux utiliser la variable $ PSScriptRoot comme emplacement du script actuel (chemin d'accès), comme dans l'exemple ci-dessous: 

if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).  

Try {
If (Test-Path 'C:\Program Files (x86)') {
    $ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise64_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x64.log`""
    Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop
    $Result= [System.Environment]::ExitCode
} Else {
    $ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x86.log`""
    Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop
    $Result= [System.Environment]::ExitCode
    }

} ### End Try block


Catch  {
    $Result = [System.Environment]::Exitcode
    [System.Environment]::Exit($Result)
   }
[System.Environment]::Exit($Result)

Dans votre cas, vous pouvez remplacer 

Start-process ... ligne avec 

Invoke-Expression $ PSScriptRoot\ScriptName.ps1

Vous pouvez en savoir plus sur les variables automatiques $ MYINVOCATION et $ PSScriptRoot sur le site Microsoft: https://msdn.Microsoft.com/en-us/powershell/reference/5.1/Microsoft.powershell.core/about/about_automatic_variables

4
Emil Bogopolskiy

Pour exécuter facilement un fichier de script dans le même dossier (ou sous-dossier de) que l'appelant, vous pouvez utiliser ceci:

# Get full path to the script:
$ScriptRoute = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, "Scriptname.ps1"))

# Execute script at location:
&"$ScriptRoute"
3
Rrr

J'ai eu un problème avec ça. Cependant, je n’ai utilisé aucune astuce $MyInvocation intelligente pour y remédier. Si vous ouvrez l'ISE en cliquant avec le bouton droit de la souris sur un fichier de script et en sélectionnant edit, puis ouvrez le deuxième script à partir de l'ISE, vous pouvez en appeler l'un de l'autre en utilisant simplement la syntaxe.\Script.ps1 normale . J'imagine que l'ISE a la notion d'un dossier en cours et que son ouverture ainsi définit le dossier en cours dans le dossier contenant les scripts . Lorsque j'appelle un script d'un autre en utilisation normale, j'utilise simplement.\script. ps1 , IMO il est faux de modifier le script juste pour le faire fonctionner correctement dans ISE ...

3
Sabroni

J'ai eu un problème similaire et résolu de cette façon.

Mon répertoire de travail est un dossier de script général et un dossier de script particulier serveur dans la même racine, je dois appeler un dossier de script particulier (appelez script général avec le paramètre du problème particulier) . Ainsi, le répertoire de travail est comme ceci

\Nico\Scripts\Script1.ps1
             \Script2.ps1
      \Problem1\Solution1.ps1
               \ParameterForSolution1.config
      \Problem2\Solution2.ps1
               \ParameterForSolution2.config

Solutions1 et Solutions2 appellent la PS1 dans le dossier Scripts en chargeant le paramètre stocké dans ParameterForSolution . Donc, dans powershell ISE, exécutez cette commande

.\Nico\Problem1\Solution1.PS1

Et le code à l'intérieur de Solution1.PS1 est:

# This is the path where my script is running
$path = split-path -parent $MyInvocation.MyCommand.Definition

# Change to root dir
cd "$path\..\.."

$script = ".\Script\Script1.PS1"

$parametro = "Problem1\ParameterForSolution1.config"
# Another set of parameter Script1.PS1 can receive for debuggin porpuose
$parametro +=' -verbose'

Invoke-Expression "$script $parametro"
1
Nico Osorio

Comment exécutez-vous les scripts intégrés PowerShell dans vos scripts? 

Comment utilisez-vous les scripts intégrés tels que 

Get-Location
pwd
ls
dir
split-path
::etc...

Celles-ci sont exécutées par votre ordinateur, vérifiant automatiquement le chemin du script.

De même, je peux exécuter mes scripts personnalisés en mettant simplement le nom du script dans le bloc de script

::sid.ps1 is a PS script I made to find the SID of any user
::it takes one argument, that argument would be the username
echo $(sid.ps1 jowers)


(returns something like)> S-X-X-XXXXXXXX-XXXXXXXXXX-XXX-XXXX


$(sid.ps1 jowers).Replace("S","X")

(returns same as above but with X instead of S)

Passez à la ligne de commande powershell et tapez

> $profile

Cela renverra le chemin d'accès à un fichier que notre ligne de commande PowerShell exécutera à chaque fois que vous ouvrez l'application.

Il ressemblera à ceci 

C:\Users\jowers\OneDrive\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1

Accédez à Documents et voyez si vous avez déjà un répertoire WindowsPowerShell. Je ne l'ai pas fait 

> cd \Users\jowers\Documents
> mkdir WindowsPowerShell
> cd WindowsPowerShell
> type file > Microsoft.PowerShellISE_profile.ps1

Nous avons maintenant créé le script qui sera lancé chaque fois que nous ouvrirons l’application PowerShell.

Nous avons fait cela afin de pouvoir ajouter notre propre dossier contenant tous nos scripts personnalisés. Créons ce dossier et je le nommerai "Bin" après les répertoires dans lesquels Mac/Linux contient ses scripts.

> mkdir \Users\jowers\Bin

Maintenant, nous voulons que ce répertoire soit ajouté à notre variable $env:path chaque fois que nous ouvrons l'application, alors revenez au répertoire WindowsPowerShell et

> start Microsoft.PowerShellISE_profile.ps1

Puis ajoutez ceci

$env:path += ";\Users\jowers\Bin"

Maintenant, le shell trouvera automatiquement vos commandes, tant que vous enregistrez vos scripts dans ce répertoire "Bin".

Relancez le PowerShell et il devrait être l'un des premiers scripts qui s'exécutent.

Exécutez ceci sur la ligne de commande après le rechargement pour voir votre nouveau répertoire dans votre variable de chemin:

> $env:Path

Maintenant, nous pouvons appeler nos scripts depuis la ligne de commande ou depuis un autre script aussi simplement:

$(customScript.ps1 arg1 arg2 ...)

Comme vous le voyez, nous devons les appeler avec l'extension .ps1 jusqu'à ce que nous leur fassions des alias. Si nous voulons avoir envie.

0