2014-01-06 30 views
5

Ich habe ein PowerShell-Modul, das eine Reihe von häufig verwendeten Business-Funktionen kapselt. Es wird normalerweise nicht von der Konsole aus aufgerufen. Vielmehr werden seine Funktionen von automatisierten Bereitstellungs- und Verwaltungsskripten aufgerufen, die das Modul importieren.Durchlauf durch -Verbose-Status zu Modul-Cmdlets

Das Modul enthält eine Protokollierungsfunktion, die in einen zentralen Protokollspeicherort schreibt. Ich möchte auch in die Write-Verbose-Funktionalität einhaken, um auch auf die Konsole zu schreiben.

#'Start Script.ps1 
#'---------------- 

import-module Corporate 
Write-Logger 'Foo' 

Meine Einschränkung ist, dass - von den im Corporate Powershell-Modul - ich brauche, um zu bestimmen, ob Script.ps1 mit dem -Verbose Parameter aufgerufen wurde. Im Idealfall möchte ich den Bestimmungscode vollständig innerhalb des Moduls selbst.

Hier ist ein Beispiel:

[CmdletBinding()] 
Param() 

New-Module -Name TempModule -ScriptBlock { 
    function Test-ModuleVerbose() { 
     [CmdletBinding()] 
     Param() 

     PROCESS { 
      $vb = ($PSCmdlet.MyInvocation.BoundParameters['Verbose'] -eq $true) 
      Write-Host ("1: Module verbose preference: " + ($PSCmdlet.MyInvocation.BoundParameters['Verbose'] -eq $true)) 
      Write-Host ("2: Module verbose preference: " + $Script:VerbosePreference) 
      Write-Host ("3: Module verbose preference: " + $VerbosePreference) 
     } 
    } 
} | Out-Null 

function Test-Verbose() { 
    [CmdletBinding()] 
    Param() 

    PROCESS { 
     Write-Host ("Verbose preference: $VerbosePreference") 
     Test-ModuleVerbose 
    } 
} 

Test-Verbose 

Speichern Sie die oben als test.ps1. Wenn von der Konsole aufgerufen:

PS C:\temp> .\test.ps1 
Verbose preference: SilentlyContinue 
1: Module verbose preference: False 
2: Module verbose preference: 
3: Module verbose preference: SilentlyContinue 

PS C:\temp> .\test.ps1 -Verbose 
VERBOSE: Exporting function 'Test-ModuleVerbose'. 
VERBOSE: Importing function 'Test-ModuleVerbose'. 
Verbose preference: Continue 
1: Module verbose preference: False 
2: Module verbose preference: 
3: Module verbose preference: SilentlyContinue 

Wie Sie sehen können, ist der $ VerbosePreference Variable von innerhalb des Moduls nicht zur Verfügung. Gibt es eine Möglichkeit, innerhalb des Moduls abzuholen, ob das aufrufende Skript mit dem Verben-Flag aufgerufen wurde.

+0

Sie können Switch-Parameter für das Skript deklarieren und dann je nach Wert eine globale Variable festlegen. Sie können die Umgebungsvariable auch setzen/aufheben und ihren Wert im Cmdlet überprüfen. – Ievgen

Antwort

7

Es gibt eine Variable mit dem Namen $ VerbosePreference, mit der Sie überprüfen können, wie die Verbose-Ausgabe gehandhabt werden soll. Was Ihnen jedoch Probleme bereitet, ist, dass Skripte in einen separaten Bereich geladen werden. Wenn Sie die Get-Help about_scopes lesen, werden Sie sehen:

Script: 
    The scope that is created while a script file runs. Only 
    the commands in the script run in the script scope. To 
    the commands in a script, the script scope is the local 
    scope.

Sie das Skript auf den aktuellen Bereich statt mit Notation Punktquelle hinzufügen können. Aus der gleichen Hilfedatei, unter der Überschrift mit Scope Mit Dot Quelle Notation wird angegeben, dass:

Scripts and functions follow all the rules of scope. You create them in a 
particular scope, and they affect only that scope unless you use a cmdlet 
parameter or a scope modifier to change that scope. 

But, you can add a script or function to the current scope by using dot 
source notation. Then, when a script runs in the current scope, any 
functions, aliases, and variables that the script creates are available 
in the current scope.

Ich schlage vor, das Lesen bis mehr über Bereiche im Get-Help about_scopes Hilfekapitel.

Für einen schnellen Test, ob das funktioniert oder nicht:

[CmdletBinding()] 
PARAM() 

New-Module -Name TempModule -ScriptBlock { 
    function Show-ModuleVerbosePreference 
    { 
     [CmdletBinding()] 
     PARAM() 

     Write-Host "Verbose preference in module function: $VerbosePreference" 
    } 
} | Out-Null 

function Show-ScriptVerbosePreference 
{ 
    [CmdletBinding()] 
    PARAM() 

    Write-Host "Verbose preference in script function: $VerbosePreference" 
} 

Show-ScriptVerbosePreference 
Show-ModuleVerbosePreference

Und wenn wir versuchen, diese Skriptdatei zu nennen unterschiedliche Methoden verwenden wir die folgende Ausgabe:

PS C:\> .\verbosity.ps1 
Verbose preference in script function: SilentlyContinue 
Verbose preference in module function: SilentlyContinue 

PS C:\> .\verbosity.ps1 -Verbose 
VERBOSE: Exporting function 'Show-ModuleVerbosePreference'. 
VERBOSE: Importing function 'Show-ModuleVerbosePreference'. 
Verbose preference in script function: Continue 
Verbose preference in module function: SilentlyContinue 

PS C:\> . .\verbosity.ps1 
Verbose preference in script function: SilentlyContinue 
Verbose preference in module function: SilentlyContinue 

PS C:\> . .\verbosity.ps1 -Verbose 
VERBOSE: Exporting function 'Show-ModuleVerbosePreference'. 
VERBOSE: Importing function 'Show-ModuleVerbosePreference'. 
Verbose preference in script function: Continue 
Verbose preference in module function: Continue

So durch den Einsatz Punktquellen-Notation Wir haben den Skriptbereich in den aktuellen Bereich eingefügt, wodurch die VerbosePreference-Einstellung auch in der Modulmethode sichtbar wird.

+0

Danke @ robert.westerlund. Ich glaube nicht, dass ich mich richtig erklärt habe. Ich weiß, wie überprüft werden kann, ob das Verbose-Flag in einem Skript festgelegt ist. Was ich brauche, ist in der Lage zu überprüfen - aus einem PowerShell-Modul - zu sehen, ob ein Skript mit dem Verbose-Flag aufgerufen wurde. Ich habe meine Frage aktualisiert, um sie besser zu erklären. – Dan

+0

Entschuldigung, ich habe dich missverstanden. Ich denke, Sie sollten sich PowerShell-Bereiche ansehen. Ich werde meine Antwort aktualisieren. –

+1

Danke @ robert.westerlund. Ich denke, dass die Skripten wahrscheinlich am nächsten sind, die ich bekomme. Sieht jedoch bizarr aus - wenn man bedenkt, dass ein Modul als wiederverwendbares Codebeispiel konzipiert ist, das von vielen Stellen aufgerufen wird, hätten Sie gedacht, dass es möglich wäre, Skriptbereichsvariablen aufzunehmen. Danke für Ihre Hilfe. – Dan

0

Versuchen Sie, die ContainsKey Methode:

$PSCmdlet.MyInvocation.BoundParameters.ContainsKey('verbose') 
+0

Wenn die BoundParameters-Auflistung im Modul ausgeführt wird, wird die BoundParameters-Auflistung immer leer angezeigt. – Dan

+0

Haben Sie den Befehl in eine Funktion eingefügt? –

0

In meinem .psm1 lege ich einen Befehl wie folgt aus:

If ((Get-PsCallStack) [1] .Arguments -like ‚* Ausführlich = True * ') {Write-Host' Das .ps1-Skript, das dieses Modul importiert, ist Verbose '};

Sie können den Skriptblock verwenden, um eine Variable wie $ VerbosePreference in Ihrem Modulbereich oder Ihre eigene eindeutige Variable für Ihre eigene Logik festzulegen.

3

Es ist möglich, die meisten allgemeinen Parameter mit den entsprechenden Einstellungsvariablen und einer Syntax wie dieser -Parameter:$ParameterPreference zu übergeben. Für den spezifischen Fall von worse ist die Syntax -Verbose:$VerbosePreference.

Es gibt ein paar Ausnahmen:

  • Debug: Der Wert der $DebugPreference wird automatisch durchsetzten, aber die-DebugSchalterkräfte$DebugPreference-Inquire angeben.
  • WhatIf: automatisch übergeben.

ich den OP-Codebeispiel geändert haben, wie folgt:

[CmdletBinding(SupportsShouldProcess=$true)] 
param(
    [Switch]$FullPassThru 
) 

New-Module -Name TempModule -ScriptBlock { 
     function Test-ModuleVerbose 
     { 
      [CmdletBinding(SupportsShouldProcess=$true)] 
      param() 

      Write-Host "1: Module: verbose parameter is bound : $($PSCmdlet.MyInvocation.BoundParameters['Verbose'])" 
      Write-Host "2: Module: verbose preference   : $VerbosePreference" 

      # Write-Verbose will just work without any change 
      Write-Verbose "Verbose" 

      # Other commands need the $VerbosePreference passed in 
      Set-Item -Path Env:\DEMONSTRATE_PASS_THRU ` 
        -Value 'You can safely delete this variable' ` 
        -Verbose:$VerbosePreference 
     } 

     function Test-ModulePreferencePassThru 
     { 
      [CmdletBinding(SupportsShouldProcess=$true)] 
      param() 

      Write-Debug "DebugPreference: $DebugPreference" 
      Write-Warning "WarningPreference: $WarningPreference" 
      Write-Error "ErrorActionPreference: $ErrorActionPreference" 

      Set-Item -Path Env:\DEMONSTRATE_PASS_THRU ` 
        -Value 'You can safely delete this variable' ` 
        -Verbose:$VerbosePreference ` 
        -WarningAction:$WarningPreference ` 
        -ErrorAction:$ErrorActionPreference 
     } 
    } | Out-Null 

function Test-Verbose 
{ 
    [CmdletBinding(SupportsShouldProcess=$true)] 
    param() 

    Write-Host ("Verbose preference: $VerbosePreference") 
    Test-ModuleVerbose -Verbose:$VerbosePreference 
} 

function Test-PreferencePassThru 
{ 
    [CmdletBinding(SupportsShouldProcess=$true)] 
    param() 

    Test-ModulePreferencePassThru -Verbose:$VerbosePreference 
} 

try 
{ 
    if ($FullPassThru -eq $false) 
    { 
     # just demonstrate -verbose pass-through 
     Test-Verbose 
    } 
    else 
    { 
     # most of the preferences can be explicitly passed-through, however: 
     # 
     # -Debug : $DebugPreference is automatically passed-through 
     #   and -Debug forces $DebugPreference to 'Inquire' 
     # -WhatIf : automatically passed-through 
     Test-ModulePreferencePassThru -Verbose:$VerbosePreference ` 
             -WarningAction:$WarningPreference ` 
             -ErrorAction:$ErrorActionPreference | Out-Null 
    } 
} 
finally 
{ 
    # cleanup 
    Remove-Item -Path Env:\DEMONSTRATE_PASS_THRU -Force | Out-Null 
} 

Speichern Sie die oben als test.ps1. Wenn von der Konsole aufgerufen:

PS C:\temp> .\test.ps1 
Verbose preference: SilentlyContinue 
1: Module: verbose parameter is bound : False 
2: Module: verbose preference   : SilentlyContinue 

PS C:\temp> .\test.ps1 -Verbose 
VERBOSE: Exporting function 'Test-ModuleVerbose'. 
VERBOSE: Exporting function 'Test-ModulePreferencePassThru'. 
VERBOSE: Importing function 'Test-ModulePreferencePassThru'. 
VERBOSE: Importing function 'Test-ModuleVerbose'. 
Verbose preference: Continue 
1: Module: verbose parameter is bound : True 
2: Module: verbose preference   : Continue 
VERBOSE: Verbose 
VERBOSE: Performing the operation "Set Item" on target "Item: DEMONSTRATE_PASS_THRU Value: You can safely delete this variable". 

Außerdem Pass-Through für $DebugPreference, $WarningPreference und $ErrorActionPreference funktioniert auch:

PS C:\temp> $VerbosePreference = 'Continue' 
PS C:\temp> $DebugPreference = 'Continue' 
PS C:\temp> $WarningPreference = 'Continue' 
PS C:\temp> $ErrorActionPreference = 'Continue' 
PS C:\temp> .\test.ps1 -FullPassThru 
VERBOSE: Exporting function 'Test-ModuleVerbose'. 
VERBOSE: Exporting function 'Test-ModulePreferencePassThru'. 
VERBOSE: Importing function 'Test-ModulePreferencePassThru'. 
VERBOSE: Importing function 'Test-ModuleVerbose'. 
DEBUG: DebugPreference: Continue 
WARNING: WarningPreference: Continue 
Test-ModulePreferencePassThru : ErrorActionPreference: Continue 
At C:\OAASMain\Online\ContainerService\Tools\docker\test.ps1:72 char:9 
+   Test-ModulePreferencePassThru -Verbose:$VerbosePreference ` 
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : NotSpecified: (:) [Write-Error], WriteErrorException 
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Test-ModulePreferencePassThru 

VERBOSE: Performing the operation "Set Item" on target "Item: DEMONSTRATE_PASS_THRU Value: You can safely delete this variable". 

-WhatIf wird automatisch durchsetzten:

PS C:\temp> .\test.ps1 -FullPassThru -WhatIf 
What if: Performing the operation "Remove Item" on target "Item: DEMONSTRATE_PASS_THRU". 

dies auch Griffe -WarningAction und -ErrorAction:

PS C:\temp> .\test.ps1 -FullPassThru -WarningAction Ignore -ErrorAction Stop 
Test-ModulePreferencePassThru : ErrorActionPreference : Stop 
At C:\OAASMain\Online\ContainerService\Tools\docker\test.ps1:72 char:9 
+   Test-ModulePreferencePassThru -Verbose:$VerbosePreference ` 
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : NotSpecified: (:) [Write-Error], WriteErrorException 
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Test-ModulePreferencePassThru