Category Archives: Win10

Error Trapping and Handling in PowerShell

How to use the Trap and Try…Catch…Finally constructs

Don Jones | Jul 20, 2010

Sometimes when something goes wrong in Windows PowerShell, it isn’t a bad thing. That is, there are certain conditions that you can anticipate and potentially deal with, such as a missing file or a computer that can’t be contacted over the network. In response, you might want to prompt the user for an action to take or just log the error so that you can try again later. Windows PowerShell makes this possible through a scheme called error trapping and handling.

First, You Need an Error

To trap and handle an error, you actually need one to occur. Technically, in PowerShell terminology, you need an exception to occur. That can actually be a little tricky to do, believe it or not. For example, try running the following command. It will fail, but pay attention to what happens:

Get-WmiObject Win32_BIOS -comp 'localhost','not-here'

First, you should see the Win32_BIOS instance from your local computer. Then, you should see an error message (unless you actually have a computer named not-here on your network). Think you’ve seen an exception? Wrong. In PowerShell, just because you’ve seen an error message doesn’t mean an exception was created. You can’t trap or handle an error message. You can only trap and handle exceptions.

What you just saw was an example of a non-terminating exception. That is, an exception really did happen, but it wasn’t so bad that the cmdlet needed to stop executing. So the cmdlet basically held the exception deep inside, suppressing its feelings of failure, and continued trying to do what you’d asked. You can’t help the cmdlet if it isn’t going to be more open with its feelings. In other words, you can’t trap and handle non-terminating exceptions. Many of the problems a cmdlet can run into will typically generate a non-terminating exception. That’s because cmdlets don’t want folks to start calling them crybabies, so if something moderately bad happens, they just shut up and keep going.

This cmdlet behavior is controlled by a built-in PowerShell variable named $ErrorActionPreference. You can view its contents by simply typing the variable’s name at the command line:

$ErrorActionPreference

By default, it’s set to Continue, which is what cmdlets do when they encounter a non-terminating error—they keep going. The cmdlets also display error messages by default, but you can shut them off by setting $ErrorActionPreference to SilentlyContinue. Try it:

$ErrorActionPreference = "SilentlyContinue"
Get-WmiObject Win32_BIOS -comp 'localhost','not-here'

This time, the failure occurred but not a word was said about it. Our cmdlet just bit its lip and kept on going, not so much as whimpering about the error. Now, this is where a lot of new PowerShell users go wrong, so I need you to picture me standing up on a table and screaming, “Do not set $ErrorActionPreference to SilentlyContinue just to make the error messages go away.”

Error messages are, by and large, good things. They tell us what’s broken. They’re like the nerves in your fingertips that tell you the stove you’re about to touch is very hotPeople who have problems with those nerves often burn themselves. We usually want to see error messages. What we don’t want to see are the error messages that we can anticipate and deal with on our own.

Just Cry Out Loud

When you anticipate a cmdlet running into a problem that you want to deal with, you need to tell that cmdlet to stop bottling up its emotions. You’re not doing this for every cmdlet across the shell, but just for a specific cmdlet that you know you can handle. Since you don’t want to make a global behavior change, you should leave $ErrorActionPreference set to Continue. Instead, you can modify the error action for just one cmdlet.

Every cmdlet in PowerShell supports a set of common parameters, one of which is -ErrorAction (which can be abbreviated -ea). It accepts the same values as $ErrorActionPreference, including stop, which tells the cmdlet to turn a non-terminating exception into a terminating exception—and terminating exceptions are ones you can trap and handle. For this example, you’d run the command

Get-WmiObject Win32_BIOS -comp 'localhost','not-here' -ea stop

Tricky Traps

The first way you can trap an error is to use a Trap construct. Listing 1 shows an example of a trap that’s defined within a function. This code works in PowerShell 1.0 as well as PowerShell 2.0.

Function Do-Something {
  Trap {
    Write-Host 'Error in function' -fore white -back red
    Continue
  }
  Write-Host 'Trying' -fore white -back black
  gwmi Win32_BIOS -comp localhost,not-here -ea stop
  Write-Host 'Tried' -fore white -back black
}

Write-Host 'Starting' -fore white -back green
Do-Something
Write-Host 'Ending' -fore white -back green

Figure 1 shows the output from the code in Listing 1. As you can see, PowerShell first displayed the line Starting. It then executed the function, which displayed the line Trying.

Results from the Trap construct in Listing 1
Figure 1: Results from the Trap construct in Listing 1

Next, PowerShell ran Get-WmiObject, which can be abbreviated as gwmi. It first ran this cmdlet against localhost, and you can see the Win32_BIOS output. But it ran into a problem trying to contact not-here, so an exception occurred. The -ea stop parameter turned that into a terminating exception, so PowerShell looked for a Trap construct within the same scope. It found one inside the function and executed it. That’s why Error in functiondisplayed. The trap finished with the Continue statement, which kept the execution inside the same scope (i.e., inside the function), and Tried was displayed. Finally, the function exited and Ending was displayed.

Traps can be tricky because they are their own scope. Specifically, they’re a child of whatever scope they live in. Consider the modified Trap construct in Listing 2.

Function Do-Something {
  Trap {
    Write-Host 'Error in function' -fore white -back red

# BEGIN CALLOUT A
    $test = 'Two'
# END CALLOUT A
    Continue
  }
  $test = 'One'
  Write-Host "Trying $test" -fore white -back black
  gwmi Win32_BIOS -comp localhost,not-here -ea stop
  Write-Host "Tried $test" -fore white -back black
}

Write-Host 'Starting' -fore white -back green
Do-Something
Write-Host 'Ending' -fore white -back green

Figure 2 shows the output from this version, and I want you to follow the value of the $test variable.

Results from the problematic Trap construct in Listing 2
Figure 2: Results from the problematic Trap construct in Listing 2

The script set the $test variable to One, and that’s displayed in the Trying One output. When the exception occurred, the trap set the $test variable to Two. However, when the trap exited, the output still displayed Tried One. What happened? As a child scope, a trap can access its parent’s variables for reading only. So, when the trap tried to modify $test, it actually created a new local $test variable, which means that $test from the parent scope (i.e., the function) was never changed. This is a real bummer if you want your trap to modify something so that your script can continue. There are ways to remedy this. For example, you can replace the command in callout A in Listing 2 with the following command to change the variable’s contents:

Set-Variable -name test -value 'Two' -scope 1

The -scope parameter treats scope 0 as the local scope, which is within the trap. The next scope up—the trap’s parent—is scope 1. So by changing test in scope 1, you’re modifying the variable that had been set to One. Note that when you use the Set-Variable cmdlet (as well as the other -Variable cmdlets), you don’t use a dollar sign ($) when specifying a variable’s name. 

There’s one more tricky bit about traps that I want to share. Take a look at the alternative Trap construct in Listing 3.

Trap {
  Write-Host 'Error in script' -fore white -back red
  Continue
}
Function Do-Something {
  Trap {
    Write-Host 'Error in function' -fore white -back red
    Break
  }
  Write-Host "Trying" -fore white -back black
  gwmi Win32_BIOS -comp localhost,not-here -ea stop
  Write-Host "Tried" -fore white -back black
}

Write-Host 'Starting' -fore white -back green
Do-Something
Write-Host 'Ending' -fore white -back green

What I’ve done is defined a trap within the script itself, prior to the function’s definition. I’ve also modified the trap within the function to use a Break statement rather than a Continue statement. The Break statement forces the trap to exit the scope in which the error occurred (in this case, the function) and to pass the exception to the parent scope, which is the script. The shell will then look to see if a trap exists in that scope, and I have indeed defined one.

Figure 3 shows what the results look like.

Results from the alternative Trap construct in Listing 3
Figure 3: Results from the alternative Trap construct in Listing 3

When the exception occurred in the function, its trap executed and “broke out of” the function. The exception was passed to the script, so its trap executed. Notice that Tried isn’t displayed. That’s because the function exited before that command could run. All you see is Ending, which is the last line in the script. Although the script’s trap concludes with the Continue statement, all it does is keep the shell’s execution in the same scope (i.e., the script). The shell can’t dive back into the function; it broke out of the function and is out for good unless you call the function afresh.

As this example shows, you can include more than one Trap construct in a script. This means you can set different traps for different types of errors. To get more details, run the command

Help about_Trap

if you’re using PowerShell 2.0. Although PowerShell 1.0 supports the Trap construct, there isn’t a Help file for it. So, if you’re using PowerShell 1.0, you need to access the information at technet.microsoft.com/en-us/library/dd347548.aspx.

Try a Different Approach

Frankly, I find the Trap construct and its scope rules pretty confusing. Fortunately, PowerShell 2.0 offers an alternative: the Try…Catch…Finally construct, which Listing 4 shows.

Try {
  gwmi Win32_BIOS -comp localhost,not-here -ea stop
} Catch {
  Write-Host 'Something bad happened' -fore white -back red
} Finally {
  Write-Host 'Glad that is over'
}

As you can see, you put the command that might fail in the Try block and the command that deals with the failure in the Catch block. You can even add a Finally block that will execute whether or not an error occurred.

Within the Catch block, you can do almost anything, including writing to log files, logging an event log entry, and sending email messages. It’s even possible to create multiple Catch blocks, each of which deals with a certain kind of error. In PowerShell 2.0, you can run the command

Help about_Try_Catch_Finally

for more details.

What’s Your Preference?

In PowerShell 1.0, you must use the Trap construct to trap and handle errors. In PowerShell 2.0, you have a choice between the Trap and Try…Catch…Finally constructs. I prefer using the latter. Not only is the Try…Catch…Finally construct easier to use, but it also keeps the error-handling logic closer to the location of the command that might fail. If you’re using PowerShell 1.0 and you often need to catch and handle exceptions, you might consider upgrading to PowerShell 2.0 so that you can take advantage of this new error trapping and handling tool.

Source: Error Trapping and Handling in PowerShell

Hide OneDrive from File Explorer – Power Tips – PowerTips – IDERA Community

Are you tired of OneDrive icons polluting your file explorer tree view? If you don’t use OneDrive, then here are two handy functions that hide and show the OneDrive icons in File Explorer:

function Disable-OneDrive
{
  $regkey1 = 'Registry::HKEY_CLASSES_ROOT\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}'
  $regkey2 = 'Registry::HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}'
    Set-ItemProperty -Path $regkey1, $regkey2 -Name System.IsPinnedToNameSpaceTree -Value 0
}


function Enable-OneDrive
{
    $regkey1 = 'Registry::HKEY_CLASSES_ROOT\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}'
    $regkey2 = 'Registry::HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}'
    Set-ItemProperty -Path $regkey1, $regkey2 -Name System.IsPinnedToNameSpaceTree -Value 1
}

Source: Hide OneDrive from File Explorer – Power Tips – PowerTips – IDERA Community

Start / Stop / Enable / Disable Terminal services from command line

We can start Terminal Services by running the command given below.

net start TermService

If the service is already running you will get the message ‘The requested service has already been started.
Sometimes you may get an error that the service could not be started.

C:\>net start termservice
The Terminal Services service is starting.
The Terminal Services service could not be started.
The service did not report an error.
More help is available by typing NET HELPMSG 3534.

This happens when Terminal Services is disabled through registry hack. You can fix this by running the below registry change command.

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v TSEnabled /t REG_DWORD /d 1 /f

You need to reboot the computer for the changes to take effect. After reboot terminal services starts automatically or you can start the service using net start command as mentioned above.

How to stop Terminal Services?

Terminal Services can’t be stopped like other services.  You get the below error when you attempt the same.

C:\>net stop termservice
The requested pause or stop is not valid for this service.

How to restart Terminal services?

Since Terminal Services can’t be stopped there is no straightforward way we can do this. Microsoft says this is by design. But in some cases restarting terminal services could be possible by killing the svchost process that runs the terminal services.We can use tasklist and taskkill commands for this.

First get the process id of the terminal services process

 tasklist /svc | findstr /C:TermService

Check if Terminal services is the only service running in this svchost. If the svchost is shared with other services then you can stop reading further. Restarting terminal services is not possible on your machine.

On my system I have got the following output.

C:\>tasklist /svc | findstr /C:TermService
svchost.exe                 1708 DcomLaunch, TermService
C:\>
As you can see DcomLaunch and TermServiceboth share the same svchost process. In this case I can't kill the process as it stops the other service also. (Note that DcomLaunch is an essential service on the system and killing it can even shutdown the system)
In the case of svchost not being shared with any other service you can go ahead and kill TermService process by the following command.
taskkill /F /PID  process_id

How to disable Terminal Services?

We can run the below command to disable terminal services.

sc config TermService start= disabled

How to enable Terminal Services?

sc config TermService start= auto

(or)

sc config TermService start= demand

Source: Start / Stop / Enable / Disable Terminal services from command line

Monitoring Windows advanced Firewall Rule changes

Starting with Windows Vista and Windows 2008, if you want to see who and when changes Windows Firewall with Advanced Security rules and other settings you must enable either the “Policy Changes” auditing category or rather the “Filtering Platform Policy Change” and “Other Policy Change Events” auditing subcategories. Afte you have enabled this auditing, system will log success and failure audits into the Security event log whenever any firewall setting changes.

you can enable the auditing with Group Policy, Local Security Policy or from command line:

auditpol /set /subcategory:”Filtering Platform Policy Change” /success:enable /failure:enable
auditpol /set /subcategory:”Other Policy Change Events” /success:enable /failure:enable

How to Track Firewall Activity with the Windows Firewall Log

In the process of filtering Internet traffic, all firewalls have some type of logging feature that documents how the firewall handled various types of traffic. These logs can provide valuable information like source and destination IP addresses, port numbers, and protocols. You can also use the Windows Firewall log file to monitor TCP and UDP connections and packets that are blocked by the firewall.

Source: How to Track Firewall Activity with the Windows Firewall Log