Dimitri Koens on November 16th, 2011

PowerShell provides some commands to manipulate services, but that doesn’t work on remote computers! The script you can find below demonstrates that stopping a service on a remote computer using Stop-Service is not working.

First I verify that the MSDTC service is running on the local machine and a remote machine: server2. If I want to stop the service on both machines I use the Stop-Service cmdlet. But this command doesn’t work on server2 when I’m piping the output from Get-Service to Stop-Service!  🙁

There are two solutions. The first is you can use the InputObject parameter as part of Stop-Service.

You can also use WMI to stop a remote service.  Just retreive the specific service from a remote computer by using the Get-WmiObject cmdlet and use the StopService method to stop the service.

WMI is intended to work remote so this command gives the correct result!  🙂

"Verifying services"
Get-Service MSDTC
Get-Service MSDTC -computer server2
"Stopping services"
Get-Service MSDTC | Stop-Service
Get-Service MSDTC -computer server2 | Stop-Service   # Stop-Service does not accept pipelined input!
"Verifying services."
Get-Service MSDTC
Get-Service MSDTC -computer server2
"Stopping remote service, alternative"
Stop-Service -InputObject (Get-Service MSDTC -ComputerName server2)
"Stopping remote service using WMI"
(Get-WmiObject win32_service -computer server2 | Where { $_.name -eq 'MSDTC' }).stopservice()

Thanks to Martin Tengvall for pointing out the -InputObject variant.

Dimitri Koens on November 15th, 2011

It’s possible to compress a folder or file since Windows NT. It’s a feature of the NTFS-filesystem. Normally we would do that on the properties of the folder or file in the Windows Explorer, but you can do this with PowerShell too! Just use this command:

Invoke-WmiMethod -Path "Win32_Directory.Name='C:\Test'" -Name compress

And to Uncompress the same folder, use this command:

Invoke-WmiMethod -Path "Win32_Directory.Name='C:\Test'" -Name uncompress

We’re talking about NTFS compression here, not the ZIP-feature introduced in Windows XP and later. You can notice that the folder is compressed by the blue color of the folder in Windows Explorer. Or you can open the properties of the folder to see whether the size on disk is smaller than the normal size. Do not try to compress items that are already compressed, like pictures (JPG…), music (MP3…), video (AVI, MPG…).

When you use WMI to execute operating system functions like this, you get a return value. When the return value is 0 (zero) this means the command functioned. Other return values can mean different things (read-only, no disk space, no permissions,…). In general: when we’re executing WMI-commands we’re allways checking the return value. You could implement it like this:

$a = Invoke-WmiMethod -Path "Win32_Directory.Name='C:\Test'" -Name compress
If ($a.returnvalue) -eq 0 { "Items successfully compressed" } else { "Something went wrong!" }

 

Dimitri Koens on November 13th, 2011

The other day I stumbled upon a nice PowerShell command to use the speech API found on modern Windows Operating Systems. With this script PowerShell can talk to you! Great for situations where you want to hear about the progress of your script. Or maybe to tell you there’s an alert instead of showing the alert. Here’s the script:

 

$a = New-Object -COM SAPI.SpVoice
$a.speak("I'm completely operational, and all my circuits are functioning perfectly.")
Dimitri Koens on November 10th, 2011

Not too long ago I migrated my e-mail, calendar and contacts to the cloud. The migration was very smooth except for one thing. For some unknown reason a reminder was added to all my all-day appointments. I use these appointments for birthdays and that sort of events. I never use a reminder on my all-day appointments but after the migration all these appointments were set with a reminder of 15 minutes before the appointment. A daily appointment starts at 0:00 and lasts until 24:00. So that means my phone urged me to wake up at 23:45 so I didn’t forget my sisters birthday!

The next morning I realised what went wrong and that I could expect a lot of nightly wakeup calls if I didn’t remove the reminders. I have a lot of daily events and was wondering if PowerShell was able to build a list of all-day events with a reminder set.

The following script uses the Outlook COM-object to retreive all your events. It selects all-day events that have a reminder set. Please note: in most cases Outlook will show a pop-up or maybe a pop-under where you’re asked for access to Outlook from PowerShell.

 

# Create the outlook application object, and connect to the calendar folder
$olApp = New-Object -COM Outlook.Application
$namespace = $olApp.GetNamespace("MAPI")
$fldCalendar = $namespace.GetDefaultFolder(9)
"Retreiving calendar items"
$items = $fldCalendar.Items
$items | Where { $_.reminderset -eq $true -and $_.alldayevent -eq $true -and $_.isrecurring -eq $true } |
Sort Start | Format-Table Start, Subject -auto | out-file .\agenda-reminders.txt

 

One of my clients asked me how to check for expired certificates. This simple script opens the certificate store through the PS-drive CERT: and lists all certificates that are soon to expire. You can change the threshold to any value in the first line. Here’s the script:

$threshold = 30   #Number of days to look for expiring certificates
$deadline = (Get-Date).AddDays($threshold)   #Set deadline date
Dir Cert:\LocalMachine\My | foreach {
If ($_.NotAfter -le $deadline) { $_ | Select Issuer, Subject, NotAfter, @{Label="Expires In (Days)";Expression={($_.NotAfter - (Get-Date)).Days}} }
}

This script can also be used for several machines at once. Just add the Invoke-Command to the Dir command and make sure PowerShell remoting has been set up by using Enable-PSRemoting on the target servers. More info by running this PowerShell command: Get-Help about_remoting.

$threshold = 30   #Number of days to look for expiring certificates
$deadline = (Get-Date).AddDays($threshold)   #Set deadline date
Invoke-Command -ComputerName Srv01, Srv02 { Dir Cert:\LocalMachine\My } | foreach {
If ($_.NotAfter -le $deadline) { $_ | Select Issuer, Subject, NotAfter, @{Label="Expires In (Days)";Expression={($_.NotAfter - (Get-Date)).Days}} }
}

Dimitri

Dimitri Koens on October 19th, 2011

Hi All,

Celebrating my first post on my new web site, let’s provide you with my ultimate PowerShell Quick Reference! I just finished work on my latest version of the PowerShell Quick Reference. You can grab a copy and use it as a reference when creating your PowerShell scripts. The document contains a lot of information I got when using PowerShell myself and teaching PowerShell at Microsoft Learning partners sites like Global Knowledge, Compu’Train, Twice, New Horizons and Centric.

Download here: PowerShell Quick Reference Dimension IT

Please send me a message and let me know what you think of the PowerShell Quick Reference.

Dimitri

Update 22 ocotber 2012: Quick Ref updated to PowerShell v3!

Today I published an update to my PowerShell Quick Reference: it’s now updated to PowerShell v3. I tried to include most notable new features of PowerShell v3 in the limited space of my Quick Reference. I really try to keep it a 2-page Quick Ref. It contains a complete new section on PowerShell v3 technology, like new modules, PowerShell web access, and improvements on the ISE. Also, I reformatted the Quick Ref to match with the Code Coloring in the ISE.

Please drop me a note on any comments, suggestions, etc… you might have, and I will happily incorporate it in a new version.

Have fun!
Dimitri

Tags: ,