Archive for the ‘PowerShell’ Category

Changelog: New-SignedScript

This is the changelog page for New-SignedScript. You will find a complete list of released versions, their dates, and the features and issues addressed in each. Please refer to the script’s main page for more information including download links, installation details, and more.

v1.1 – 06-10-2012

  1. Better handling when there is more than one code signing cert. Script now finds the first valid code signing cert and uses that.
  2. Better validation that the script is successfully signed

v1.0 – 09-20-2012

  1. Initial version
Categories: PowerShell Tags: , ,

Module: ExchangeServices – Functions to stop/start/query Exchange services

April 1, 2014 2 comments


Exchange 2013 logo 128x128Being someone who’s converted from Exchange to Lync, I have the luxury of cmdlets for managing Lync services. This includes starting, stopping, and querying those services. I’ve heard from a few Exchange guys who have said it would be nice if the Exchange guys had the same ability. Sure, you can manually type a PowerShell query each time, but why not convert that into some functions? I’ve created a module that has three functions in it. Start-ExWindowsService, which will start any Exchange service that is not disabled and not currently running. Stop-ExWindowsService will stop all running Exchange services. Get-ExWindowsService, which will display all Exchange services and their status and startup type. And finally, Set-ExWindowsServiceRecoveryOptions sets all Exchange related services to automatically restart in the event of a service failure.



Start-ExWindowsService [[-ComputerName] ] [[-Name] ] [-WhatIf] [-Confirm] []
Stop-ExWindowsService [[-ComputerName] ] [[-Name] ] [-Force] [-WhatIf] [-Confirm] []
Get-ExWindowsService [[-ComputerName] ] [[-Name] ] [-WhatIf ] [-Confirm ] []
Set-ExWindowsServiceRecoveryOptions [[-ComputerName] ] [-WhatIf] [-Confirm]


Open PowerShell and type $env:PSModulePath. Note that it will generally include two paths. One is to c:\Windows\System32\WindowsPowerShell\v1.0\Modules\. Placing the module in this location will make it available to everyone who uses that computer. The other path is to a subfolder of your My Documents folder. Something like C:\Users\administrator\Documents\WindowsPowerShell\Modules. Placing the module in there will make it available just to you. In either case, unzip the contents of the zip file, including the folder, to the modules folder. One thing to note: if you place the module in your personal modules folder, it will not show in the list when you run Get-Module -ListAvailable. But it will still work fine. Import the module by typing Import-Module ExchangeServices


v1.1 – 01-26-2015 –

v1.0 – 04-01-2014 –


See the changelog for information on what’s changed/included in each version.


Categories: Exchange Server, PowerShell Tags:

New Syntax Highlighting and Auto-Complete Files for UltraEdit includes PowerShell v4, AD, Lync 2013, and Exchange 2013

March 12, 2014 Leave a comment

Syntax highlighting

Updated the wordfile a little bit. This one includes all previous functions as well as the following:

  1. PowerShell v4 cmdlets (the ones available when you open a new v4 session).
  2. Exchange 2013 SP1 cmdlets
  3. Lync 2013 cmdlets
  4. Active Directory cmdlets

That adds up to 2834 cmdlets/functions that get syntax highlighting on top of the 137 aliases that are also in the file. The file also has variable highlighting, as well as operators and comp operators highlighting.

Formatting changes include the following:

  1. code folding for (), so your long param() blocks can now be collapsed/expanded.
  2. code folding for region/endregion. This mimics the behavior of ISE.

If you’d like to change the colors and/or fonts used for highlighting, go to View>Themes>Manage Themes, as the styling in the wordfile is ignored starting with v20 of UltraEdit.

manage themes

As with all other wordfiles, they are stored in “%appdata%\IDMComp\UltraEdit\Wordfiles\”, unless you change the path in Advanced>Configuration>Editor Display>Syntax Highlighting.

wordfile path

You can optionally set the “Highlight new file as:” to PowerShell, as I do (also shown above).

As soon as you place this wordfile in that folder, you should see PowerShell as an option under View>View as (Highlighting File Type)

view as highlighting


I’ve also created an auto complete file that contains the same cmdlet/function names as the syntax highlighting file. When enabled, you get tab completion of cmdlet and function names similar to the PowerShell console and ISE. Note, however, that in UltraEdit, you only get auto-complete of the cmdlet/function names, not their parameters.

You can save the file anywhere. Then, go to Advanced>Configuration>Editor>Word Wrap/Tab Settings to specify the location within UltraEdit:

auto-complete path

Then go to Auto-complete and check the box “Show auto-complete dialog automatically” and also enter a number in the box. 5 works for me.

auto-complete options

Now, when typing a cmdlet/function that’s in the auto-complete file, you’ll get suggestions.

auto-complete suggestions

Up/down errors navigate through the list, and tab uses the highlighted suggestion.


Function: Set-PowerPlan – Adjust The Power Plan of a Server

February 25, 2014 1 comment

Just something I worked up based on a suggestion by someone. This will change the power plan of the machine it’s run on. This can be critical if you want to ensure that the machine doesn’t go to sleep while an extended process is running. Simply run the function with the desired power plan and the change is immediate. For example:

Set-PowerPlan "High Performance"

The three power plans you can choose from are “high performance”, “balanced”, and Power Saver. That’s all there is to it.

function Set-PowerPlan {
	[CmdletBinding(SupportsShouldProcess = $True)]
	param (
		[ValidateSet("High performance", "Balanced", "Power saver")]
		[string] $PreferredPlan = "High Performance"
	Write-Verbose "Setting power plan to `"$PreferredPlan`""
	$guid = (Get-WmiObject -Class Win32_PowerPlan -Namespace root\cimv2\power -Filter "ElementName='$PreferredPlan'").InstanceID.ToString()
	$regex = [regex]"{(.*?)}$"
	$plan = $regex.Match($guid).groups[1].value 
	powercfg -S $plan
	$Output = "Power plan set to "
	$Output += "`"" + ((Get-WmiObject -Class Win32_PowerPlan -Namespace root\cimv2\power -Filter "IsActive='$True'").ElementName) + "`""
	Write-Verbose $Output
Categories: PowerShell Tags: ,

Function: New-TrustedIESite – Add URLs to IE’s Security Zones

February 8, 2014 2 comments


This function probably doesn’t have a lot of users to most people. But in Lync, adding the Simple URL for the Lync Server Control Panel to the Local Intranet zone resolves the issue of having to enter credentials each time. Of course, I like to automate the configuration of things, so I whipped up this little function, and it will be included in some of my build scripts. The script basically creates the required registry entries under HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains. Immediately after running the function, we can see the new entry in Internet Explorer

Internet Explorer Trusted Intranet Zone

Internet Explorer Trusted Intranet Zone


New-TrustedIESite [[-url] ] [[-zone] ] []

Zones are as follows:

1 Local Intranet
2 Trusted Sites
3 Internet
4 Restricted Sites


New-TrustedIESite -url -zone 1

Will add to the Local Intranet zone


v1.0 – 02-08-2014 –

One liners: Get the Top 5 Errors From An Event Log

Powershell_logo-137x137As part of an Active Directory Health Check (think “ADRAP”), I needed to document the top errors and warnings in several event logs, including the System, Application, DNS, Directory Service, FRS, and others. This list also needed to include the source of the errors. Since there were a bunch of domain controllers, I didn’t want to spend all day manually looking through event logs, filtering, etc. PowerShell to the rescue.

Get-EventLog is pretty self explanatory. We tell this command we want to look at the system event log, and we’re only interested in errors. We could look for other event types, too, such as Information, FailureAudit, SuccessAudit, and Warning. Get-EventLog can filter based on dates, usernames, etc.

We then take the output of that, and pipe it to Group-Object (or “Group” for short). We group based on source and eventID. This lumps all of the same events with the same eventID together as one object. This is important, because if there are errors with the same source, but different eventID, we want those listed separately.

Next, we use Sort-Object, or “sort”, to arrange the results into a usable list, with the highest numbers at the top. Since we only need the top 5 in the list for this exercise, Select-Object, or “select”, comes into play. This will return just the number of objects we specify. In this case, that’s 5. Since we pass the -first parameter to this cmdlet, we get the first 5 results that were piped from the previous command. Essentially, the highest 5 objects. And lastly, we display just the count and the name using Format-Table, or “ft”. Since we grouped the source and eventID together, the name will be the name of the source, and the corresponding eventID. The output looks like this:

Count Name
----- ----
  179 Microsoft-Windows-GroupPolicy, 1006
   30 Service Control Manager, 7031
   19 Microsoft-Windows-Hyper-V-Netvsc, 2
   15 Service Control Manager, 7034
   10 Microsoft-Windows-WindowsUpdateClient, 20

Exactly what I was after. The top 5 errors in the system event log, sorted by how many times the error appeared in the log, with the source name and eventID, sorted. The one-liner looks like this:

Get-EventLog -LogName system -EntryType error | Group source,eventid | Sort count -desc | Select -first 5 | Ft count,name

We could also strip off the ft stuff, and use Export-Csv to dump the results to a csv file.

Get-EventLog -LogName system -EntryType error | Group source,eventid | Sort count -desc | Select -first 5 | Export-Csv c:\SystemErrors.csv -Not

Pretty straightforward, and fairly quick, as long as your event logs aren’t huge. We can even target remote computers by appending the -ComputerName parameter to the Get-EventLog cmdlet. For example:

Get-EventLog -LogName system -EntryType error -ComputerName mycomputer.contoso.local | Group source,eventid | Sort count -desc | Select -first 5 | Export-Csv c:\SystemErrors.csv -Not


Categories: PowerShell Tags: ,

Function: Get-PstFiles – List All .pst Files In A Given Path, With Name, Path, Size, and Owner

May 13, 2013 4 comments

Exchange 2013 logo 128x128Description

If you need to make a list of the .pst files in a given path, this function should help. It will get all .pst files, their name, path, size (in MB), and owner. This should help if you’re looking at importing the files in Exchange Server. If you’d like to export the results to a file, use the -file switch, with a filename, and the function will save the info to a .csv file.


Get-PstFiles [[-path] ] [[-filter] ] [[-file] ] [-WhatIf] [-Confirm] []


v1.1 – 05-13-2013

Syntax Highlighting File for UltraEdit Includes Exchange 2010/2013, Lync 2010/2013, and ActiveDirectory cmdlets

May 8, 2013 3 comments

In a previous post, Exchange 2010 and Lync 2010 PowerShell syntax highlighting file for UltraEdit, I included the cmdlets for both Exchange 2010 and Lync 2010. In this new file, I’ve included Lync 2010, Lync 2013, Exchange 2010, Exchange 2013, and Active Directory cmdlets for highlighting. If you use UltraEdit, this wordfile may make life a little easier.

Download the file here:

One liners: Get All Exchange Users Who Are Configured for Forwarding

May 7, 2013 3 comments

Exchange 2013 logo 128x128Due to some legal requirements, I had a needed to list all users who were configured in Exchange to forward elsewhere. This was to ensure that mail wasn’t automatically leaving the environment. A simple, single line in the shell is all that’s needed to give me what I need.

Open Exchange Management Shell, and enter this:

Get-Mailbox -Resultsize Unlimited | ? {$_.ForwardingAddress}

We can clean this up and make it a little more presentable using something like:

Get-Mailbox -Resultsize Unlimited | Where-Object {$_.ForwardingAddress} | Select-Object Name, @{Expression={$_.ForwardingAddress};Label="Forwarded to"}, @{Expression={$_.DeliverToMailboxAndForward};Label="Mailbox & Forward"}

And the results are a small table that shows the user name, which object mail is being forwarded to, and whether the mailbox is configured to both store and forward:


This allowed me to take a look at those user accounts, and disable the forwarding, forcing the users to use their Exchange mailbox.

For a long list, or if you just want the info in a file, we can export the results to a .csv using Export-Csv. To do this, use:

Get-Mailbox -Resultsize Unlimited | Where-Object {$_.ForwardingAddress -ne $null} | Select-Object Name, @{Expression={$_.ForwardingAddress};Label="Forwarded to"}, @{Expression={$_.DeliverToMailboxAndForward};Label="Mailbox & Forward"} | Export-Csv c:\forwardedusers.csv -NoTypeInformation

Function: Set-TimeZone – Configure Time Zone via PowerShell

March 4, 2013 1 comment

Powershell_logo-137x137It’s easy to just double-click on the time in the system tray and set the time and time zone when building a new server. You may even have a GPO that does this for you. That’s all fine and dandy. But GPOs don’t work for member servers, and if you build a lot of servers, like I do, it’s a repetitive task – something perfectly suited for PowerShell.

With this function, we do nothing more than call tzutil.exe with the timezone name. Nothing fancy. I added some validation to make sure that the timezone specified is truly one of the 100 valid time zones that tzutile.exe should recognize and accept.

So, now, in your server provisioning script, merely call the function, Set-TimeZone, with the desired timezone. For example:

Set-TimeZone "Pacific Standard Time"

The script defaults to “Eastern Standard Time” if you don’t supply a timezone. That’s it. There is no screen output for this function. Here’s the function:

function Set-TimeZone {
  [CmdletBinding(SupportsShouldProcess = $True)]
    [Parameter(ValueFromPipeline = $False, ValueFromPipelineByPropertyName = $True, Mandatory = $False)]
    [ValidateSet("Dateline Standard Time","UTC-11","Hawaiian Standard Time","Alaskan Standard Time","Pacific Standard Time (Mexico)","Pacific Standard Time","US Mountain Standard Time","Mountain Standard Time (Mexico)","Mountain Standard Time","Central America Standard Time","Central Standard Time","Central Standard Time (Mexico)","Canada Central Standard Time","SA Pacific Standard Time","Eastern Standard Time","US Eastern Standard Time","Venezuela Standard Time","Paraguay Standard Time","Atlantic Standard Time","Central Brazilian Standard Time","SA Western Standard Time","Pacific SA Standard Time","Newfoundland Standard Time","E. South America Standard Time","Argentina Standard Time","SA Eastern Standard Time","Greenland Standard Time","Montevideo Standard Time","Bahia Standard Time","UTC-02","Mid-Atlantic Standard Time","Azores Standard Time","Cape Verde Standard Time","Morocco Standard Time","UTC","GMT Standard Time","Greenwich Standard Time","W. Europe Standard Time","Central Europe Standard Time","Romance Standard Time","Central European Standard Time","W. Central Africa Standard Time","Namibia Standard Time","Jordan Standard Time","GTB Standard Time","Middle East Standard Time","Egypt Standard Time","Syria Standard Time","E. Europe Standard Time","South Africa Standard Time","FLE Standard Time","Turkey Standard Time","Israel Standard Time","Arabic Standard Time","Kaliningrad Standard Time","Arab Standard Time","E. Africa Standard Time","Iran Standard Time","Arabian Standard Time","Azerbaijan Standard Time","Russian Standard Time","Mauritius Standard Time","Georgian Standard Time","Caucasus Standard Time","Afghanistan Standard Time","Pakistan Standard Time","West Asia Standard Time","India Standard Time","Sri Lanka Standard Time","Nepal Standard Time","Central Asia Standard Time","Bangladesh Standard Time","Ekaterinburg Standard Time","Myanmar Standard Time","SE Asia Standard Time","N. Central Asia Standard Time","China Standard Time","North Asia Standard Time","Singapore Standard Time","W. Australia Standard Time","Taipei Standard Time","Ulaanbaatar Standard Time","North Asia East Standard Time","Tokyo Standard Time","Korea Standard Time","Cen. Australia Standard Time","AUS Central Standard Time","E. Australia Standard Time","AUS Eastern Standard Time","West Pacific Standard Time","Tasmania Standard Time","Yakutsk Standard Time","Central Pacific Standard Time","Vladivostok Standard Time","New Zealand Standard Time","UTC+12","Fiji Standard Time","Magadan Standard Time","Tonga Standard Time","Samoa Standard Time")]
    [string]$TimeZone = "Eastern Standard Time"

  $process = New-Object System.Diagnostics.Process 
  $process.StartInfo.WindowStyle = "Hidden" 
  $process.StartInfo.FileName = "tzutil.exe" 
  $process.StartInfo.Arguments = "/s `"$TimeZone`"" 
  $process.Start() | Out-Null 
} # end function Set-TimeZone