Reputation: 103
I'm new to PowerShell and have been trying to pass credentials to dot-sourced scripts. The idea is to have one main file that I can just load and then use the sourced functions and it'll be cleaner.
Here's an example of what I've tried so far:
Functions.ps1
$credentials = Get-Credential -Message "Please enter your credentials."
. .\Unlock.ps1 -Credential $credentials
Unlock.ps1
function Unlock-Account {
param(
[Parameter(Mandatory = $true)]
[string] $username,
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]
[PSCredential] $Credential
)
try {
Unlock-ADAccount -Identity $username -Credential $credentials
}
catch {
Write-Output " Could not unlock $username"
}
}
Upvotes: 2
Views: 2002
Reputation: 200293
Dot-sourcing a script does not automatically invoke functions in the sourced script. What you'd normally do in your scenario is this:
$credentials = Get-Credential -Message "Please enter your credentials."
. .\Unlock.ps1
Unlock-Account 'somename' -Credential $credentials
If you want to avoid having to specify -Credential $credentials
with every invocation of the function you could make the credential parameter optional and assign a default value:
Param(
[Parameter(Mandatory=$true)]
[string]$Username,
[Parameter(
Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
ValueFromPipeline=$true
)]
[PSCredential]$Credential = $global:Credential
)
That way $Credential
will automatically assume the value from the variable $Credential
in the global scope if that variable has already been defined. Beware, though, that the parameter will have an empty value if the global variable has not been defined when the function is invoked.
Technically speaking you can dot-source a script and pass parameters to it:
Param(
[Parameter(Mandatory=$true)]
[PSCredential]$Credential
)
function Unlock-Account {
Param(
[Parameter(Mandatory = $true)]
[string]$Username,
[Parameter(
Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
ValueFromPipeline=$true
)]
[PSCredential]$Credential = $script:Credential
)
...
}
and then dot-source the script and invoke the function like this:
$credentials = Get-Credential -Message "Please enter your credentials."
. .\Unlock.ps1 -Credential $credentials
Unlock-Account 'somename'
However, that approach would be quite ... unconventional. I do not recommend taking this route.
Upvotes: 3
Reputation: 1295
Dot sourcing a PS1 is effectively running the contents of that file in your session as if you had copied and pasted the whole thing into your command line. There's not really a concept of passing arguments to a dot sourced file.
However, there are a number of ways to effectively do what you want to do.
One way is to add the command that you want to run to the end of your script. So add the following to the last line of your script file (after the function's closing curly brace):
# You could optionally add the line that gathers the credential here as well.
Unlock-Account -Credential $credentials
I don't personally like this method because it forces you to always run the function when sometimes you just want the function to be available. Another way you can do this is by just making the script file run like a function. Essentially, you just remove the function declaration in the script and keep the rest. Then you just call the script like a function instead of dot sourcing it.
So your script contents becomes:
param(
[Parameter(Mandatory = $true)]
[string] $username,
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]
[PSCredential] $Credential
)
try {
Unlock-ADAccount -Identity $username -Credential $credentials
}
catch {
Write-Output " Could not unlock $username"
}
And you call it like this:
.\Unlock.ps1 -Credential $credentials
This method is pretty useful for a quick one-off script. But if you end up with a lot of these that are all related to each other, you're probably better off creating a real PowerShell module.
The last method is probably the least used, but still perfectly valid if you want to keep the script dot source'able and not actually call anything when it's dot sourced. You can just combine the dot source command and your function call into a one-liner command like this:
. .\Unlock.ps1; Unlock-Account -Credential $credentials
Upvotes: 1