Ik wil aanroepuitvoering voor een myScript1.ps1-script in een tweede myScript2.ps1-script in Powershell ISE.
De volgende code in MyScript2.ps1 werkt prima vanuit Powershell Administration, maar werkt niet binnen PowerShell ISE:
#Call myScript1 from myScript2
invoke-expression -Command .\myScript1.ps1
Ik krijg de volgende foutmelding wanneer ik MyScript2.ps1 uitvoer vanuit PowerShell ISE:
De term ‘.\myScript1.ps1’ wordt niet herkend als de naam van een cmdlet, functie, scriptbestand of bruikbaar programma. Controleer de spelling van de naam, of als een pad is opgenomen, controleer of het pad correct is en probeer het opnieuw.
Antwoord 1, autoriteit 100%
Om de locatie van een script te vinden, gebruikt u Split-Path $MyInvocation.MyCommand.Path
(zorg ervoor dat u dit in de scriptcontext gebruikt).
De reden waarom je dat zou moeten gebruiken en niet iets anders kan worden geïllustreerd met dit voorbeeldscript.
## ScriptTest.ps1
Write-Host "InvocationName:" $MyInvocation.InvocationName
Write-Host "Path:" $MyInvocation.MyCommand.Path
Hier zijn enkele resultaten.
PS C:\Users\JasonAr> .\ScriptTest.ps1 Aanroepnaam: .\ScriptTest.ps1 Pad: C:\Users\JasonAr\ScriptTest.ps1 PS C:\Gebruikers\JasonAr> . .\ScriptTest.ps1 Aanroepnaam: . Pad: C:\Users\JasonAr\ScriptTest.ps1 PS C:\Gebruikers\JasonAr> & ".\ScriptTest.ps1" Aanroepnaam: & Pad: C:\Users\JasonAr\ScriptTest.ps1
In PowerShell 3.0en hoger kunt u de automatische variabele $PSScriptRoot
gebruiken:
## ScriptTest.ps1
Write-Host "Script:" $PSCommandPath
Write-Host "Path:" $PSScriptRoot
PS C: \ Users \ Jarcher & GT; . \ Scripttest.ps1 Script: C: \ gebruikers \ Jarcher \ scripttest.ps1 Pad: C: \ gebruikers \ Jarcher
Antwoord 2, Autoriteit 64%
Ik bel MyScript1.PS1 van MyScript2.PS1.
Aangenomen van beide script staan op dezelfde locatie, ontvang eerst de locatie van het script met behulp van deze opdracht:
$PSScriptRoot
En voeg vervolgens de scriptnaam toe waarin u als volgt wilt bellen:
& "$PSScriptRoot\myScript1.ps1"
Dit zou moeten werken.
Antwoord 3, Autoriteit 39%
Het huidige pad van MyScript1.PS1 is niet hetzelfde als MyScript2.PS1. U kunt het mappad van MyScript2.PS1 krijgen en deze aansluiten op MyScript1.PS1 en vervolgens uitvoeren. Beide scripts moeten op dezelfde locatie staan.
## MyScript2.ps1 ##
$ScriptPath = Split-Path $MyInvocation.InvocationName
& "$ScriptPath\MyScript1.ps1"
Antwoord 4, Autoriteit 20%
One Line-oplossing:
& ((Split-Path $MyInvocation.InvocationName) + "\MyScript1.ps1")
Antwoord 5, Autoriteit 15%
Dit is gewoon aanvullende informatie aan antwoorden
Om het argument in het andere bestand
door te geven
waar u argument verwacht
printnaam.ps1
Param(
[Parameter( Mandatory = $true)]
$printName = "Joe"
)
Write-Host $printName
Hoe het bestand op te roepen
Param(
[Parameter( Mandatory = $false)]
$name = "Joe"
)
& ((Split-Path $MyInvocation.InvocationName) + "\PrintName.ps1") -printName $name
Als u geen invoer opgeeft, wordt deze standaard ingesteld op “Joe” en wordt dit als argument doorgegeven aan het argument printName in het bestand PrintName.ps1
die op zijn beurt de “Joe”string
. zal afdrukken
Antwoord 6, autoriteit 4%
Misschien heb je het antwoord al gevonden, maar dit is wat ik doe.
Ik plaats deze regel meestal aan het begin van mijn installatiescripts:
if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).
Dan kan ik $PSScriptRoot variabele gebruiken als locatie van het huidige script(pad), zoals in het onderstaande voorbeeld:
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)
In jouw geval kun je
. vervangen
Start-proces…regel met
Invoke-Expression $PSScriptRoot\ScriptName.ps1
Je kunt meer lezen over $MYINVOCATION en $PSScriptRoot automatische variabelen op de Microsoft-site: https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_automatic_variables
Antwoord 7, autoriteit 4%
Om eenvoudig een scriptbestand uit te voeren in dezelfde map (of submap van) als de beller kunt u dit gebruiken:
# Get full path to the script:
$ScriptRoute = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, "Scriptname.ps1"))
# Execute script at location:
&"$ScriptRoute"
Antwoord 8, autoriteit 3%
Ik had hier een probleem mee. Ik heb echter geen slimme $MyInvocation
dingen gebruikt om het te repareren. Als u de ISE opent door met de rechtermuisknop op een scriptbestand te klikken en edit
te selecteren en vervolgens het tweede script vanuit de ISE opent, kunt u het ene van het andere aanroepen door gewoon de normale .\script.ps1 te gebruiken syntaxis.
Mijn gok is dat de ISE het idee heeft van een huidige map en deze op deze manier te openen, stelt de huidige map in op de map die de scripts bevat.
Wanneer ik bij normaal gebruik het ene script van het andere aanroep, gebruik ik gewoon .\script.ps1, IMO is het verkeerd om het script aan te passen om het in de ISE correct te laten werken…
Antwoord 9, autoriteit 3%
Ik had een soortgelijk probleem en heb het op deze manier opgelost.
Mijn werkdirectory is een algemene scriptmap en een aantal specifieke scriptmap in dezelfde root, ik moet een bepaalde scriptmap aanroepen (die het algemene script oproept met de parameter van het specifieke probleem).
Dus de werkmap ziet er zo uit
\Nico\Scripts\Script1.ps1
\Script2.ps1
\Problem1\Solution1.ps1
\ParameterForSolution1.config
\Problem2\Solution2.ps1
\ParameterForSolution2.config
Solutions1 en Solutions2 roepen de PS1 aan in de map Scripts en laden de parameter die is opgeslagen in ParameterForSolution.
Dus in powershell ISE voer ik deze opdracht uit
.\Nico\Problem1\Solution1.PS1
En de code in Solution1.PS1 is:
# 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"
Antwoord 10, autoriteit 2%
Ik dien mijn voorbeeld in ter overweging. Zo noem ik wat code uit een controllerscript in de tools die ik maak. De scripts die het werk doen, moeten ook parameters accepteren, dus dit voorbeeld laat zien hoe je ze kunt doorgeven. Het gaat er wel van uit dat het script dat wordt aangeroepen zich in dezelfde map bevindt als het controllerscript (script dat de oproep doet).
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string[]]
$Computername,
[Parameter(Mandatory = $true)]
[DateTime]
$StartTime,
[Parameter(Mandatory = $true)]
[DateTime]
$EndTime
)
$ZAEventLogDataSplat = @{
"Computername" = $Computername
"StartTime" = $StartTime
"EndTime" = $EndTime
}
& "$PSScriptRoot\Get-ZAEventLogData.ps1" @ZAEventLogDataSplat
Het bovenstaande is een controllerscript dat 3 parameters accepteert. Deze worden gedefinieerd in het parameterblok. Het controllerscript roept vervolgens het script Get-ZAEventLogData.ps1 aan. Dit script accepteert bijvoorbeeld ook dezelfde 3 parameters. Wanneer het controllerscript het script aanroept dat het werk doet, moet het dit aanroepen en de parameters doorgeven. Het bovenstaande laat zien hoe ik het doe door te splatten.
Antwoord 11
Hoe voer je ingebouwde PowerShell-scripts in je scripts uit?
Hoe gebruik je ingebouwde scripts zoals
Get-Location
pwd
ls
dir
split-path
::etc...
Deze worden uitgevoerd door uw computer en controleren automatisch het pad van het script.
Op dezelfde manier kan ik mijn aangepaste scripts uitvoeren door gewoon de naam van het script in het scriptblok te zetten
::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)
Ga naar de powershell-opdrachtregel en typ
> $profile
Hiermee wordt het pad geretourneerd naar een bestand dat onze PowerShell-opdrachtregel elke keer dat u de app opent, uitvoert.
Het ziet er zo uit
C:\Users\jowers\OneDrive\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1
Ga naar Documenten en kijk of u al een WindowsPowerShell-map hebt. Ik niet, dus
> cd \Users\jowers\Documents
> mkdir WindowsPowerShell
> cd WindowsPowerShell
> type file > Microsoft.PowerShellISE_profile.ps1
We hebben nu het script gemaakt dat elke keer dat we de PowerShell-app openen, wordt gestart.
De reden dat we dat deden, was om onze eigen map toe te voegen die al onze aangepaste scripts bevat. Laten we die map maken en ik noem hem “Bin” naar de mappen waarin Mac/Linux zijn scripts bevat.
> mkdir \Users\jowers\Bin
Nu willen we dat die map wordt toegevoegd aan onze $env:path
-variabele elke keer dat we de app openen, dus ga terug naar de WindowsPowerShell
-directory en
> start Microsoft.PowerShellISE_profile.ps1
Voeg dit dan toe
$env:path += ";\Users\jowers\Bin"
Nu vindt de shell uw opdrachten automatisch, zolang u uw scripts opslaat in die “Bin” -map.
Relaunch de PowerShell en het moet een van de eerste scripts zijn die execute.
Voer dit uit op de opdrachtregel na het herladen om uw nieuwe map in uw padvariabele te zien:
> $env:Path
Nu kunnen we onze scripts bellen vanaf de opdrachtregel of vanuit een ander script als eenvoudigweg als dit:
$(customScript.ps1 arg1 arg2 ...)
Zoals u ziet, moeten we ze bellen met de .ps1
-extensie totdat we aliassen voor hen maken. Als we willen letten.
Antwoord 12
U kunt ook de volgende opdrachten gebruiken:
$Patch = Join-Path -Path $PSScriptRoot -ChildPath "\patch.ps1"<br>
Invoke-Expression "& `"$Patch`""