Hoe geef ik een schakelparameter door aan een ander PowerShell-script?

Ik heb twee PowerShell-scripts met schakelparameters:

compile-tool1.ps1:

[CmdletBinding()]
param(
  [switch]$VHDL2008
)
Write-Host "VHDL-2008 is enabled: $VHDL2008"

compileer.ps1:

[CmdletBinding()]
param(
  [switch]$VHDL2008
)
if (-not $VHDL2008)
{ compile-tool1.ps1            }
else
{ compile-tool1.ps1 -VHDL2008  }

Hoe kan ik een schakelparameter doorgeven aan een ander PowerShell-script, zonder grote if..then..elseof case-instructies te schrijven?

Ik wil de parameter $VHDL2008van compile-tool1.ps1niet converteren naar bool, omdat beide scripts front-end scripts (gebruikt door gebruikers). De laatste is een wrapper op hoog niveau voor meerdere compile-tool*.ps1-scripts.


Antwoord 1, autoriteit 100%

U kunt $trueof $falseop een schakelaar specificeren met behulp van de dubbele punt-syntaxis:

compile-tool1.ps1 -VHDL2008:$true
compile-tool1.ps1 -VHDL2008:$false

Dus geef gewoon de werkelijke waarde door:

compile-tool1.ps1 -VHDL2008:$VHDL2008

Antwoord 2, autoriteit 9%

Probeer

compile-tool1.ps1 -VHDL2008:$VHDL2008.IsPresent 

Antwoord 3

Ervan uitgaande dat je de ontwikkeling aan het herhalen was, is het zeer waarschijnlijk dat je op een gegeven moment andere schakelaars en parameters aan je hoofdscript gaat toevoegen die worden doorgegeven aan het volgende aangeroepen script. Als u de vorige antwoorden gebruikt, zou u elke oproep moeten zoeken en de regel moeten herschrijven telkens wanneer u een parameter toevoegt. In dat geval kunt u de overhead vermijden door het volgende te doen:

.\compile-tool1.ps1 $($PSBoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key) $($_.Value)"})

De automatische variabele $PSBoundParametersis een hashtabel die de parameters bevat die expliciet aan het script zijn doorgegeven.

Houd er rekening mee dat script.ps1 -SomeSwitchgelijk is aan script.ps1 -SomeSwitch $trueen script.ps1gelijk is aan script.ps1 -SomeSwitch $false. Daarom is het opnemen van de schakelaar die is ingesteld op ‘false’ gelijk aan het niet opnemen ervan.


Antwoord 4

Volgens de blog van een powershell-team (link hieronder) is er sinds V2 een techniek die splatting wordt genoemd. In principe gebruik je de automatische variabele @PsBoundParameters om alle parameters door te sturen. Details over splatting en het verschil tussen @ en $ worden uitgelegd in het Microsoft Docs-artikel (link hieronder.)

Voorbeeld:

ouder.ps1

#Begin of parent.ps1     
param(
    [Switch] $MySwitch
    )
 Import-Module .\child.psm1     
Call-Child @psBoundParameters
#End of parent.ps1

kind.psm1

# Begin of child.psm1
function Call-Child {
    param(
        [switch] $MySwitch
    )
    if ($MySwitch){
        Write-Output "`$MySwitch was specified"
    } else {
        Write-Output "`$MySwitch is missing"
    }
}
#End of child.psm1

Nu kunnen we het bovenliggende script aanroepen met of zonder de schakelaar

PS V:\sof\splatting> .\parent.ps1 
$MySwitch is missing
PS V:\sof\splatting> .\parent.ps1 -MySwitch
$MySwitch was specified
PS V:\sof\splatting> 

Bijwerken

In mijn oorspronkelijke antwoord heb ik de kinderen gesourced in plaats van het als een module te importeren. Het lijkt erop dat het sourcen van een ander script in het origineel de variabelen van de ouder alleen maar zichtbaar maakt voor alle kinderen, dus dit werkt ook:

# Begin of child.ps1
function Call-Child {
    if ($MySwitch){
        Write-Output "`$MySwitch was specified"
    } else {
        Write-Output "`$MySwitch is missing"
    }
}
#End of child.ps1

met

#Begin of parent.ps1     
param(
    [Switch] $MySwitch
    )
. .\child.ps1    
 Call-Child # Not even specifying @psBoundParameters   
#End of parent.ps1

Misschien is dit niet de beste manier om een ​​programma te maken, maar zo werkt het wel.

Over Splatting (Microsoft Docs)

Hoe en waarom Splatting gebruiken ([switch] parameters doorgeven)


Antwoord 5

Een andere oplossing. Als u uw parameter declareert met een standaardwaarde van $false:

[switch] $VHDL2008 = $false

Het volgende (de optie -VHDL2008 zonder waarde) stelt $VHDL2008 in op $true:

compile-tool1.ps1 -VHDL2008

Als u in plaats daarvan de optie -VHDL2008 weglaat, dwingt dit $VHDL2008 om de standaardwaarde $false te gebruiken:

compile-tool1.ps1

Deze voorbeelden zijn handig bij het aanroepen van een Powershell-script vanuit een bat-script, omdat het lastig is om een ​​$true/$false bool van bat naar Powershell door te geven, omdat de bat zal proberen de bool om te zetten in een string, wat resulteert in de fout:

Cannot process argument transformation on parameter 'VHDL2008'. 
Cannot convert value "System.String" to type "System.Management.Automation.SwitchParameter". 
Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0.

Other episodes