Start-DscConfiguration doesn't throw exceptions?
Asked Answered
R

3

6

I noticed that if applying a configuration through Start-DscConfiguration fails, it writes to the error stream but doesn't throw an Exception? That is, if I do the following:

try{
    Start-DscConfiguration -Path ".\MyConfig" -Wait -Verbose
}catch{
    #...
}

...it never ends up in the catch handler. I suspect this may have something to do with the fact that without the "-Wait", Start-DscConfiguration starts an async job for this, and async commands probably don't throw exceptions, but in a synchronous scenario, I would very much like to know if my configuration could be applied.

What is the proper way to determine if Start-DscConfiguration has completed succesfully?

Redfish answered 29/11, 2014 at 10:40 Comment(1)
To whoever downvoted me: it would be nice if you at least left a comment explaining why.Redfish
G
7

The only way I know is to check the global "$error" variable and compare the number of error records before and after your call to Start-DscConfiguration. If there's more afterwards then something must have gone wrong during the call, so throw your own exception:

Configuration TestErrorHandling {
    Node "localhost" {
        Script ErroringResource {
            GetScript =  { return $null; }
            TestScript = { return $false; }
            SetScript = { throw new-object System.InvalidOperationException; }
        }
    }
}

$errorCount = $error.Count;

write-host "starting dsc configuration"
$mof = TestErrorHandling;
Start-DscConfiguration TestErrorHandling –Wait –Verbose;
write-host "dsc configuration finished"

if( $error.Count -gt $errorCount )
{
    $dscErrors = $error[$errorCount..($error.Count - 1)];
    write-host "the following errors occurred during dsc configuration";
    write-host ($dscErrors | fl * | out-string);
    throw $dscErrors[-1];
}
Gillen answered 29/11, 2014 at 12:51 Comment(3)
I was hoping there would be a more elegant way (this still feels a bit like a work-around). Until then, this definitely works - thanks for your thorough explanation.Redfish
I wonder all these years later if you ever found a more elegant approach?Presentation
It's been a long time since I did any DSC - I just thought that maybe the -ErrorVariable parameter would* work and would contain just the errors from that command rather than an accumulated list of all errors in the script, but I just tried it and it doesn't seem to populate the variable, so I guess that's not actually an option...Gillen
R
2

There's another way to make it cause an exception. Try saving it into the ErrorVariable like this :

try
{
   Start-DscConfiguration -Path ".\MyConfig" -Wait -Verbose -ErrorVariable ev
}
catch
{
    $myException = $_
}

Weirdly so, this throws the exception when there's an error (which is what you wanted). You can get the value of your exception in the $myexception variable, and also could get just a one liner description of your error using $ev

PS: Note that while mentioning ev in the errorVariable parameter, you do it without the '$' symbol - since you're only specifying the variable 'name'.

Ranson answered 26/1, 2015 at 22:40 Comment(0)
G
1

Start-DscConfiguration when used without -Wait will create a job object - with one child job for every computername. PowerShell job objects have an Error stream which contains all the errors. You can check this stream as well

$job = Start-DscConfiguration -Force -Verbose -Path C:\Temp\Demo\ -ComputerName localhost

Receive-Job $job -Wait

'Errors in job = ' + ($job.childjobs[0].Error.Count)

Grendel answered 6/3, 2015 at 18:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.