Author Posts

February 20, 2014 at 1:20 pm

Hello,

I want my script to access PSCredential type parameter which is optional. I want to use credentials of current user if it's not supplied but use $cred if it's supplied and I plan to use that parameter to use later say in Get-WMIObject calls.
How do I properly initialize $cred parameter?

[Parameter(Mandatory=$False)]
[PSCredential]$cred;

February 20, 2014 at 1:33 pm

Splatting can be helpful here:

[CmdletBinding()]
param (
    [pscredential]
    $Credential
)

# Setting up the hashtable which will either be empty, or contain your $Credential object

$credHash = @{}
if ($Credential)
{
    $credHash['Credential'] = $Credential
}

# Splatting the hashtable to other commands.  If $credHash contains a credential object, it gets
# passed to the cmdlet.  If it's empty, nothing is passed to the -Credential parameter, and Get-WmiObject
# defaults to using the current user's credentials.

Get-WmiObject -Class Win32_OperatingSystem @credHash

I've read that you can also set your parameter's default value to [pscredential]::Empty , but that some cmdlets don't properly handle that value. It's more reliable to use the splatting approach.

February 20, 2014 at 2:25 pm

Another option:

[CmdletBinding()]
param (
[pscredential]
$Credential
)
if ($Credential)
{
$PSDefaultParameterValues = $PSDefaultParameterValues.clone()
$PSDefaultParameterValues['*:Credential'] = $Credential
}

Now any cmdlet that takes a -Credential parameter will automatically use that credential, and no other changes are required in the script.

Cloning the $PSDefaultParameterValues is necessary to preserve whatever default parameters values are set in the session, while protecting the preference variable in the parent scope. Unlike the other preference variables, it's a hash table, which means just adding a new key would actually update the preference in the parent scope, and would still be in effect when the script exits.

February 21, 2014 at 8:51 am

You guys are awesome!

What notations in '*:Credential' means in brackets? I assume brackets are used to specify which value you need to pull out of hashtable based on that key. But both "*" and ":" I assume signify something special

February 21, 2014 at 9:07 am

The complete details of that variable are in the about_Parameters_Default_Values help file. It's a hashtable / Dictionary with a special syntax enforced for keys. The keys must be ":"; the part can be *, in which case it applies to all commands with .

You do need to be running at least PowerShell 3.0 to use $PSDefaultParameterValues, though; keep that in mind if you've still got older versions floating around.

February 24, 2014 at 9:45 am

Hello,

Got following error when using substitution method on following command. How do I remove credentials when specifically using Add-Content? Issue is that credentials which I specify manually when I run cmdLet is network credentials to query AD in different domain but I have to write to local file system where that account do not have permissions. Is it still possible to use substituion method instead of creating HastTable?

Add-Content -Path @"c:\out.txt" -Value ("Processing account")


The FileSystem provider supports credentials only on the New-PSDrive cmdlet. Perform the operation again without specifying credentials.
At C:\ExpirationMailer.ps1:78 char:1
+ Add-Content -Path $OutputFile -Value ("Processing account $_.givenName $_.Surnam ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotImplemented: (:) [], PSNotSupportedException
+ FullyQualifiedErrorId : NotSupported

February 24, 2014 at 9:50 am

You just have to be more selective in which cmdlets the substitution applies to. A key of '*:Credential' means your PSCredential gets applied to any cmdlet which has a "Credential" parameter. You could do something like this, instead:

$PSDefaultParameterValues['*-AD*:Credential'] = $Credential

That would only apply to cmdlets whose name contained "-AD". You can make multiple entries to the table, if you need to use some cmdlets and not others.

Personally, I prefer the splatting / hashtable approach, for its PowerShell 2.0 compatibility and finer control in situations like this.