Author Posts

January 4, 2016 at 10:51 pm

I'm writing up DSC script resource that creates a scheduled task that runs under a particular user. Unfortunately the Register-ScheduledTask cmdlet doesn't accept [System.Management.Automation.PSCredential] in any parameter. It only accepts -User and -Password. So I'm not too sure on how to encrypt the password. I've tried using PsDscRunAsCredential = $Credential to run the DSC resource under that particular user but Register-ScheduledTask still requires -User and -Password to be populated if you want the task to be set to "Run whether user is logged on or not"

Does anyone know how would I go about encrypting the password in the MOF file as the standard DSC way isn't going to work in this situation or is going to be a case of using a combination of....


January 4, 2016 at 11:17 pm

As far as I know, a mof file is only designed to run in the system context, plus you always have to be wary of needing multiple credentials for multiple configurations in your MOF so you should pretty much ONLY be signing passwords inside the configuration mof 🙂

The short answer to your question is that it's fairly easy: just add a param () to you configuration and then make sure the variable is present in your configuration data.

quick example:

Configuration SCCMConfiguration
    param (
    Import-DSCResource -ModuleName cSCCM
    Node $AllNodes.NodeName
        cCMFolder Device_All
            FolderName = "_All"
            FolderType = "Device Collection"
            ParentFolder = "Root"
            SCCMAdministratorCredential = $SCCMAdministratorCredential
            Ensure = "Present"

$Nodes = @{
    AllNodes = @(
        	NodeName = "SCCM01"

Now in this fictitious example, if I run the config ill be prompted for the required creds "SCCMAdministratorCredentials". Bam, the generated mof will store the account.

Also note the entry "PSDscAllowPlainTextPassword=$true". Unforuntatley this means that password is in clear text and anyone with vi/notepad/whatever can see that password in the mof. If you want that encrypted, you need a certificate on the target server and a copy of the public cert and it's thumbprint ... and you just add that to the config data so it looks like this:

$Nodes = @{
    AllNodes = @(
        	NodeName = "SCCM01"
                CertificateFile = "C:\path\cert.cer"
                Thumbprint = "123412412412412"

Now in this case you encrypt the password using the supplied certificate. But there's a catch: you need to configure the LCM on your node and tell it which cert to use to decrypt that password.

Hope that helps!

January 5, 2016 at 2:42 am

Justin, I appreciate your post. Thank you.

I'm already using a certificate to encrypted the $Credential you supply to the MOF file. The problem is I need to encrypt a second set of credentials because Register-ScheduledTask doesn't accept [PsCredential]. So I'm wondering what other people do in this instance?

January 5, 2016 at 4:50 am

You can make your DSC resource accept a [pscredential] argument, and then just extract the plain-text password within the resource's code. Here's a quick demonstration of how you can do that:

$cred = Get-Credential

$username = $cred.UserName

$ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($cred.Password)
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr)

Write-Host "Username: $username , Password: $password"

Alternatively, in WMF 5, you don't really have to worry about it, because now the entire MOF file can be encrypted instead of just the pscredential passwords.

January 5, 2016 at 5:07 am

Dave that is exactly what I was looking for, thank you. I'll give it a try tomorrow.

However...I'm really liking the idea of encrypting the entire MOF file. I had a look at but it doesn't mention anything about encrypting the entire MOF. Any hints on how to do it?

January 5, 2016 at 5:38 am

Well crap... I was sure I read something about encrypting the whole MOF file, but that may have been in reference to a preview version or something. Looking at my Windows 10 system right now, it looks like that's only partially implemented. (It adds a "PasswordEncrypted" ContentType header to the MOF, but doesn't actually encrypt the text, which is kind of silly. It also only does this if the MOF contains a PSCredential object, which is also silly. If I specify a certificate, just encrypt the stupid thing! 🙂 )

January 5, 2016 at 5:56 am

Just got clarification on this:

"The encryption of the MOF is handled by the LCM once it gets the MOF.

It is not a compile time thing."

That's too bad; this means the MOF file on the pull server will still be sitting there in plain text, as well as the copy on the machine where you compiled it.

January 5, 2016 at 2:44 pm

>That's too bad; this means the MOF file on the pull server will still be sitting there in
> plain text, as well as the copy on the machine where you compiled it.

Oh well. Maybe a feature for WMF 6 then 😉

Dave, how would you access the credentials object in a script resource? My script resource is just a couple lines of code so I can't justify creating a proper dsc resource instead.

Script CredExtractTest
PsDscRunAsCredential = $Credential
Credential = $Credential

GetScript = {
$Status = Test-Path -Path C:\Temp\credtest.txt
GetScript = $GetScript
SetScript = $SetScript
TestScript = $TestScript
Result = $Status

SetScript = {
$ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($Credential.Password)
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr)

$Credential.UserName | Out-File C:\Temp\credtest.txt
$password | Out-File C:\Temp\credtest.txt -Append

TestScript = {
$Status = Test-Path -Path C:\Temp\credtest.txt
$Status -eq $True

VERBOSE: [TestServer01]: [[Script]CredExtractTest] Performing the operation "Set-TargetResource" on target "Executing the SetScript with the user supplied credential".
Invoke-CimMethod : Exception calling "SecureStringToGlobalAllocUnicode" with "1" argument(s): "Value cannot be null. Parameter name: s"

January 12, 2016 at 4:51 am

I'm not sure if you can. The credential encryption code in DSC only kicks in if you have a DSC resource with a property of type [pscredential]. The Script resource doesn't.

January 12, 2016 at 3:26 pm

I understand. Thanks for confirming Dave.