Reputation: 532
I have a powershell module that defines some basic functions that write log events according to corporate standard, and another single function which creates the folder the log file should go into, and restarts the logging app service.
Each function that writes different severities of log event needs to use the $LogFileLocation
variable (set in the function that creates the folder, restarts the service and generally gets the system ready to start logging) but the $LogFileLocation
variable is only available inside the function that does setup.
How can I make it available to the other functions, including to any script functions from a script which imports the module? I've tried Global:$LogFileLocation
instead of just $LogFileLocation
but this doesn't seem to make it a global variable.
Upvotes: 1
Views: 2881
Reputation: 24430
Define this function in your module:
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
}
}
This uses the New-Variable
command to assign your path value to a variable, setting that variable as a constant (as presumably once set you don't want other functions to change this path at runtime; since that could lead to unpredictable results with a widely scoped variable).
The Scope
parameter takes an argument of 1
, meaning that this variable is scoped to the container of the function's definition; which in your case is the module script. i.e. Defining this function in the module then calling at runtime has the same effect as writing $LogFileLocation = 'c:\path\to\file.log'
in the module's code; only you now have a way to avoid hard-coding that path in your module.
The ValidateScript
option on path has the logic Test-Path $_ -PathType Leaf
. i.e. we want to ensure that the path being referred to is valid / already exists; and that it's a file, not a directory. Of course, you may want to only validate the directory exists then create a new file at runtime; or maybe create anything that doesn't already exist at runtime... you can tweak this logic as you require.
The Resolve-Path
is used in case someone passes in a relative path (i.e. '.\default.log'
; as if the working directory changes as the script runs, the file which this refers to would also change. By resolving it to an absolute path when set this location is then locked down.
Rather than referring to the variable by name elsewhere in the module (i.e. $Script:LogFileLocation
or $LogFileLocation
), I'd recommend adding a Get method to allow logic to check that this variable was set, then using that. Of course, that may be an additional overhead that's not worth it (i.e. if performance is more important than robustness)... depending on your requirements.
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)
} catch {
if ($DefaultIfNotSet) {
$path = Set-MyModuleLogPath $DefaultPath #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
}
}
Upvotes: 3
Reputation: 2152
Put the variable and its assignment ($LogFile = 'C:\path\to\file.log'
), at the top of the .psm1 file, and it'll becomes a module-level variable, thus making it available to all the functions in the module.
Upvotes: 2