Author Posts

January 4, 2016 at 7:26 pm

This may be a security thing, but basically I have some functions that I originally kept in a file.ps1, and would simply "import-module file.ps1", use the functions, then move on with my life.

I've sense decided to turn them into a more formal module by converting it into a file.schema.psm1 and accompanying file.psd1 manifest. LItterally little more than a rename and adding a manifest.

But one of my functions no longer works after this change. It' a function that does something a little less conventional: it reads an xml file of username and passwords and then converts them all to credentials. This way I can quickly "import" an xml file of username/passwords to be called by whatever other random scripts I want to run ... less typing ... yippie.

Now that it's a more "formal module" the function "appears" to work ... but after running I have no variables in memory to be called. Sample snippet here:

Function New-PasswordScriptVariable
{
param(
    [Parameter(Mandatory=$True)][String]$Name,
    [Parameter(Mandatory=$True)][String]$User,
    [Parameter(Mandatory=$True)][String]$Password
    )

    $SecurePass = ConvertTo-SecureString $Password -AsPlainText -Force
    Invoke-Expression ("`$$Name = New-Object System.Management.Automation.PSCredential $User, `$SecurePass")
}

So run this in a prompt or save as a ps1, import, and run it and you can do something easily like "new-passwordScriptVariable -name sample -user "contoso\jdoe" -password "blah"

then notice you have $sample ready to go. However ... package it away as a module ... nothing happens (or maybe sometime happens but I never see the variable in my user context).

Tips?

January 4, 2016 at 8:42 pm

There's very little value in having your function be responsible for creating the variable. You can just return the credential object, and have the calling code assign it to a variable if it wants to. For example:

Function New-PasswordScriptVariable
{
param(
    [Parameter(Mandatory=$True)][String]$User,
    [Parameter(Mandatory=$True)][String]$Password
    )

    $SecurePass = ConvertTo-SecureString $Password -AsPlainText -Force
    New-Object System.Management.Automation.PSCredential $User, $SecurePass
}

# calling code

$cred = New-Credential -User Bob -Password Whatever

If you really want your function to set a variable out in the scope of the calling function (and a module is involved), you need to use the $PSCmdlet variable.

Incidentally, Invoke-Expression is very dangerous if you're working with input that is not completely safe / trusted. This example will avoid that, since it's not needed anyway:

Function New-PasswordScriptVariable
{
param(
    [Parameter(Mandatory=$True)][String]$Name,
    [Parameter(Mandatory=$True)][String]$User,
    [Parameter(Mandatory=$True)][String]$Password
    )

    $SecurePass = ConvertTo-SecureString $Password -AsPlainText -Force
    $cred = New-Object System.Management.Automation.PSCredential $User, $SecurePass
    
    $PSCmdlet.SessionState.PSVariable.Set($Name, $cred)
}

January 4, 2016 at 9:29 pm

I appreciate the help, perhaps my "poor man's password vault" is just a bad idea.

Essentially your first example doesn't spit out a "variable variable". it spits out credentials to a fixed name variable. That's not what I'm trying to accomplish, as I'm hoping to be able to create multiple variables so that I can do things like essentially dump some common credentials out then call them ass needed for different things.

install-sql.ps1 -creds $SQLSVC
install-DC.ps1 -creds $DomainAdmin

Basically I pull them up in one line ... run all my various credential required cmdlets ... close the session when I'm done. It's a convenience thing.

Your second example may be better if I"m planning to run this function from within another script ... if I understand what it's doing ... but I'm not certain I do ... but Ill give it a go and see what happens 🙂

Edit: looks like I got it working (thank you!)

Your second example was key ... with one missing piece being I needed [cmdletbinding()] defined .... got that info from your blog 🙂