0

For example, I have the below function:

Function enable-RemoteDesktopConnections
{
    Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" -Name "fDenyTSConnections" -Value 00000000
    Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" -Name "fSingleSessionPerUser" -Value 00000000
    Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name "UserAuthentication" -Value 00000000
}

This simply enables Remote Desktop. Now, I want to have some error handling within the function, but equally return a success or failure to the call itself so I can update values further in the script.

Can you wrap functions in a IF Statement and then use boolean to determine whether it was successful or not?

For example, take this function, where $a = "3"

Function foo {
 If($a -eq "1"){
    $true
 }else{
    $false
 }}

We then wrap the Function in an IF i.e. if the function returned true, success, or false, Fail.

If(foo){
  Write-Host "Success"
}else{
  Write-Host "Fail"
}

Is there a better way, a more effective method, a more robust approach.

3
  • Are you asking if that works or if there is a better/more correct/more idiomatic way? Commented Nov 24, 2015 at 15:01
  • I guess, both really. Commented Nov 24, 2015 at 15:07
  • 2
    As written, it's not clear what you're asking. More effective how? More robust for which scenarios? Are you asking about functions that only return a boolean? Are you asking how to write the functions or the tests or both? Commented Nov 24, 2015 at 15:08

2 Answers 2

4

If each Set-ItemProperty call is dependant on the previous call, you might want to leverage the power of transactions:

Function Enable-RemoteDesktopConnections
{
    param()

    # Set ErrorAction preference, only applies to function scope
    $ErrorActionPreference = "SilentlyContinue"

    # Initiate a transaction that automatically rolls back on error
    Start-Transaction -RollbackPreference Error

    # Do your thing with the -UseTransaction parameter switch
    Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" -Name "fDenyTSConnections" -Value 00000000 -UseTransaction
    Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" -Name "fSingleSessionPerUser" -Value 00000000 -UseTransaction
    Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name "UserAuthentication" -Value 00000000 -UseTransaction

    # Attempt to complete transaction
    Complete-Transaction

    # return the status of whether the last call succeeded or not
    return $?
}
Sign up to request clarification or add additional context in comments.

Comments

2

Since this is a programming style question, here are some PS style elements to consider. In general, built-in PS cmdlets don't use return codes. They use exceptions, return errors in the error stream, or they return $null.

Briefly, exceptions allow a lot of flexibility in how errors are handled:

  • In a function you write, error handling can be ignored and left for the caller to deal with
  • Or error handling can be performed against a whole block of code
  • Or error handling can be performed against a specific line of code
  • You can use finally to perform resource cleanup regardless of whether error happened
  • You can use Trap to handle all errors at a given scope (along with sub scopes) in the same place
  • Using $ErrorActionPreference or the -ErrorAction common parameter you can turn exceptions into errors or errors into exceptions

Transactions, discussed in the previous answer, are a way to turn multiple actions into a single atomic action. In a transaction either all the individual actions succeed or none of them do. In the case of the 3 registry settings for RDP that may or may not be important. I kind of doubt it is though. Otherwise whoever designed those registry settings wouldn't have designed them that way - to easy for users to get into trouble.

Transactions don't help with signalling errors. So if your concern is that the caller of enable-RemoteDesktopConnections know whether it succeeded or not transactions don't directly enable that. They do make sure that all 3 registry operations succeeded/failed, so your error signalling can be binary (yes or no, exception or no exception). As opposed to your error signalling being something like: 1) all registry updates performed, 2) some performed and some failed, and 3) they all failed.

Also the transaction makes sure the registry is never in a state where some of the 3 changes were made and some weren't - due to the actions of your script. However there's nothing to prevent another program from changing a subset of those 3 values.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.