2017-03-23 10 views
1

私は会社の標準に従ってログイベントを書き込むいくつかの基本機能を定義するpowershellモジュールと、ログファイルが入るフォルダを作成し、ロギングアプリサービスを再起動する別の関数を定義しています。Powershellモジュール内の変数を、そのモジュール内の他の関数からアクセスできるようにするにはどうすればよいですか?

ログイベントのさまざまな重大度を書き込む各関数は、$LogFileLocation変数を使用する必要があります(フォルダを作成する関数で設定し、サービスを再起動してシステムにログを開始させます)。$LogFileLocation変数は、セットアップを行う関数。

モジュールをインポートするスクリプトの任意のスクリプト関数を含む、他の関数でそれを使用できるようにするにはどうすればよいですか?私は$LogFileLocationの代わりにGlobal:$LogFileLocationを試しましたが、これはグローバル変数には見えません。

+0

既存の答えはおそらく正しいアプローチですが、FYIのグローバルスコープへの正しい道は '$ global:logfilelocation'です –

答えて

2

.psm1ファイルの先頭に、変数とその割り当て($LogFile = 'C:\path\to\file.log')を入れて、それがよこうしてモジュールにには、利用可能なすべての機能を作り、モジュールレベルの変数となります。

1

モジュールでこの関数を定義する:

Function Set-MyModuleLogPath { 
    [CmdletBinding()] 
    param (
     [Parameter(Mandatory=$true)] 
     [ValidateScript({Test-Path $_ -PathType Leaf})] #include this if you want to ensure the path exists before using (or add logic to create the path below) 
     [String]$Path 
    ) 
    process { 
     (New-Variable -Name 'LogFileLocation' -Value (Resolve-Path $Path).Path -Option 'Constant' -Scope 1 -PassThru).Value 
     #For more info on Scope see: https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_scopes 
    } 
} 

これは定数としてその変数を設定し、変数にパスの値を割り当てることがNew-Variableコマンドを使用しています(おそらく一度設定して、あなたが他の機能を望んでいません実行時にこのパスを変更すると、広くスコープされた変数では予期しない結果につながる可能性があります)。

Scopeの引数は、1という引数をとります。つまり、この変数は関数の定義のコンテナにスコープされています。あなたの場合はモジュールスクリプトです。モジュール内でこの関数を定義すると、実行時に呼び出すと、モジュールのコードに$LogFileLocation = 'c:\path\to\file.log'と書くのと同じ効果があります。あなたのモジュールでそのパスをハードコーディングすることを避ける方法しかありません。

パス上のValidateScriptオプションのロジックは、Test-Path $_ -PathType Leafです。すなわち、参照されているパスが有効であることを保証したい、または既に存在することを保証したい。ディレクトリではなくファイルであることを確認します。もちろん、ディレクトリが存在することを検証し、実行時に新しいファイルを作成したいだけかもしれません。実行時にすでに存在していないものを作成することもできます。必要に応じてこのロジックを調整することができます。

Resolve-Pathは、誰かが相対パスを使用する場合に使用されます(つまり、'.\default.log';スクリプトの実行時に作業ディレクトリが変更された場合と同様に、これも参照するファイルが変更されます)。

モジュール内の別の名前で変数を参照するのではなく(つまり、$Script:LogFileLocationまたは$LogFileLocation)、この変数が設定されていることをロジックが確認できるようにGetメソッドを追加することをお勧めします。もちろん、それはそれに値するものではない追加のオーバーヘッド(つまり、パフォーマンスが堅牢性よりも重要である場合)...あなたの要件に応じて可能性があります。

Function Get-MyModuleLogPath { 
    [CmdletBinding(DefaultParameterSetName='ErrorIfNotSet')] 
    param (
     [Parameter(ParameterSetName='DefaultIfNotSet', Mandatory=$true)] 
     [switch]$DefaultIfNotSet 
     , 
     [Parameter(ParameterSetName='DefaultIfNotSet')] 
     [string]$DefaultPath = '.\default.log' 
    ) 
    process { 
     try { 
      $path = (Get-Variable -Name 'LogFileLocation' -Scope 1 -ValueOnly -ErrorAction Stop).Value 
     } catch { 
      if ($DefaultIfNotSet) { 
       $path = Set-MyModuleLogPath $path #once we've used the default we want it to become locked as the constant; so this log path won't change at runtime 
      } else { 
       throw "Please run 'Set-ModuleLogPath' to define a log path before calling 'Get-ModuleLogPath', or use the '-DefaultIfNotSet' switch to allow the default path to be used" 
      } 
     } 
     $path 
    } 
} 
関連する問題