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.
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
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"
Une solution en ligne:
& ((Split-Path $MyInvocation.InvocationName) + "\MyScript1.ps1")
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.
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
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
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"
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 ...
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"
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.