blog.powershell.no

On Windows PowerShell and other admin-related topics

Send text messages (SMS) using Windows PowerShell

In Microsoft Office Outlook there is an add-in called Microsoft Outlook SMS Add-in (MOSA), which provides the ability to send text messages (SMS). MOSA is builtin to Outlook 2010, and are available as a plugin for Outlook 2003 and 2007 here.

On the Microsoft Office Online Help you can find guidance on how to set up the service account and sending a text message. To find the necessary settings for your mobile service provider, go here.

I looked into the COM-object for Outlook, and it turned out to be rather easy to use this API to send text messages from MOSA.
Based on that I created an Advanced function in Windows PowerShell v2 called Send-SMSMessage.

To define the function you can either paste it directly into your session, save it as a ps1 script-file and dot source it, put it into your profile or into a module.

When that is accomplished you can find usage information using the consistent Get-Help cmdlet:

image

Sample usage:

image

The function checks if Outlook are installed, and breaks out with a warning if not:

image

It also checks to see if an account are configured for Text Messaging (SMS):

image

Any errors related to service availabilty, correct phonenumber format and so on are handled by the SMS Add-in itself. These error messages appear in the Outlook inbox:

image

The function is tested from Outlook 2010 only, but should work from 2003 and 2007 also when MOSA is installed.

Since the function accepts ValueFromPipeline and ValueFromPipelineByPropertyName you can use it in conjunction with e.g. the Active Directory cmdlets for Windows PowerShell.  A given example of this retrieves all users from Active Directory with a derfined mobilephone number and sends them an SMS with their username:

image

Another practical usage scenario I can think of is combining the Send-SMSMessage function with user provisioning, sending the new user it`s new username and password.
Feel free to come up with more usage scenarios in the comment field below.

Bonus tips

  • You can also send MMS messages using the Outlook COM-object. To do this, use “olMobileItemMMS” instead of “olMobileItemSMS” in the following line: $NewMessage = $outlook.CreateItem(“olMobileItemMMS”). You should also look into the other properties for MMS messages, like the Attachment-property.
  • If you got more than one account configured for text messaging, you can use the SendUsingAccount-property to define which account to send from.
  • If you use the Norwegian mobile service provider Telenor, the “Service Provider URL” in the account settings is https://telenormobil.no/smapi/services/omsv3_service

July 21, 2010 Posted by Jan Egil Ring | Active Directory management, Microsoft Outlook, Scripting, Windows PowerShell | , , | 2 Comments

Backing up Group Policy Objects using Windows PowerShell

A best practice in domain environments are backing up the Group Policy Objects regularly. Even though a GPO may be restored by restoring a system state backup from a domain controller to an alternate location, and then copy the contents from the deleted GPO to a new GPO to restore the settings, this may be a hazzle since it`s not pretty straightforward. It also requires you to restart the domain controller affected in Directory Services Restore Mode.
PowerShell MVP Don Jones has written a good article on this topic, available here.

For those of you who may not want to do GPO restore the hard way, or buy a commercial third party product, I would encourage you to schedule regular GPO backups using the Windows PowerShell Group Policy-module available in Windows Server 2008 R2, as well as RSAT in Windows 7.
To accomplish this, I`ve written a small script which backs up all modified GPO`s in the specified timespan. I would generally recommend to have the script run once a day, thereby setting the timespan-variable to the last 24 hours. The script are called Backup-ModifiedGPOs.ps1, and available from here.

All Group Policy Objects modified in the specified timespan are backup up to the specified backup path.
Also, an HTML-report are created for each GPO-backup, with the unique backup GUID as part of the filename. This way you can easily see what settings each backup contains.

When restoring a GPO, you must first note the GUID of the backup you want to restore. Then you can restore the GPO by using the Restore-GPO cmdlet in the Group Policy-module. Sample usage:

image

Administrators who feels more comfortable working with the GUI, may use the Group Policy Management Console to do the restore.

The following procedure from the Group Policy Planning and Deployment Guide on Microsoft TechNet describes how to accomplish the restore operation from the GUI:

To view the list of GPO backups

  1. In the GPMC console tree, expand the forest or domain that contains the GPOs that you want to back up.
  2. Right-click Group Policy Objects, and the click Manage Backups.
  3. In the Manage Backups dialog box, enter the path to the location where you stored the GPO backups that you want to view. Alternatively, you can click Browse, locate the folder that contains the GPO backups, and then click OK.
  4. To specify that only the most recent version of the GPOs be displayed in the Backed up GPOs list, select the Show only the latest version of each GPO check box. Click Close.

Using the GPMC to restore GPOs

You can also restore GPOs. This operation restores a backed-up GPO to the same domain from which it was backed up. You cannot restore a GPO from a backup into a domain that is different from the GPO’s original domain.

To restore a previous version of an existing GPO

  1. In the GPMC console tree, expand Group Policy Objects in the forest or domain that contains the GPOs that you want to restore.
  2. Right-click the GPO that you want to restore to a previous version, and then click Restore from Backup.
  3. When the Restore Group Policy Object Wizard opens, follow the instructions in the wizard, and then click Finish.
  4. After the restore operation completes, a summary will state whether the restore succeeded. Click OK.

To restore a deleted GPO

  1. In the GPMC console tree, expand the forest or domain that contains the GPO that you want to restore.
  2. Right-click Group Policy Objects, and then click Manage Backups.
  3. In the Manage Backups dialog box, click Browse, and then locate the file that contains your backed-up GPOs.
  4. In the Backed up GPOs list, click the GPO that you want to restore, and then click Restore.
  5. When you are prompted to confirm the restore operation, click OK.
  6. After the restore operation completes, a summary will state whether the restore succeeded. Click OK. Click Close.

 

Important: Since Group Policy links are stored on the Organizational Unit objects in Active Directory, this information are not backup up and also not restore. However, the HTML backup-reports contains this information, so you may manually re-link the GPO to the correct OU(s).

Also note that WMI filters and IPSec policies are not backed up by the backup feature in the Group Policy Management Console. For more information on how to manage these items, see the before mentioned Group Policy Planning and Deployment Guide.

June 15, 2010 Posted by Jan Egil Ring | Active Directory management, Group Policy, Scripting, Windows 7, Windows PowerShell, Windows Server 2008 R2 | 1 Comment

Dynamic Remote Desktop Connection Manager connection list

 

Microsoft recently released a free tool for managing multiple remote desktop connections called “Remote Desktop Connection Manager”.

A sample screenshot:

image

There are several nice features, such as “Connect group” which lets you connect to all servers in a group at once:

image

On the “Group Properties” you may set common settings for all connections in the group, like logon credentials:

image

Further, there are group properties for RDS Gateway (formerly TS Gateway), display settings, local resources and so on.

There are several applications for remote desktop connections on the market, and some of them got these settings as a per server setting. It`s nice to be able to group servers and configure common settings.

Dynamically creating the connection list

When you work in larger environments with hundreds, maybe thousands of servers, setting up each connection manually isn`t an option.

Since Remote Desktop Connection Manager stores the config-files in xml-files, it`s rather easy to create dynamic config-files for a domain using Windows PowerShell. I`ve created a script to accomplish this, called New-RDCManFile.ps1, available from here. It uses Microsoft`s PowerShell-module for Active Directory, which is available in Windows Server 2008 R2 and RSAT for Windows 7.

The script does the following:
Creates a template xml-file
Inserts the logged on user`s domain name in the file properties
Inserts the logged on user`s domain name in the group properties
Inserts the logged on user`s username in the logoncredentials section
Inserts the logged on user`s domain name in the logoncredentials section
Retrieves all computer objects from Active Directory with the word “server” in the operatingsystem property
Adds each computer object as a server object
Saves the XML-file to %userprofile%\domain-name.rdg

When done you can open the rdg-file in Remote Desktop Connection Manager. I would recommend you to insert your password in the Group Properties to avoid being asked for credentials for each connection.

Feel free to customize the script to your needs, in example by editing the XML-template to edit the Group Properties. Another customization might be creating a group for each server OU for enhanced overview in larger environments.

If you would rather use Quest`s PowerShell Commands for Active Directory (which works on downlevel operatingsystems like Windows XP and Windows Server 2003), or any other way to retrieve the server names, you may customize this on line 110.

You might also want to schedule the script to run on a regular basis, saving the file to a central location. This way the IT personnel will always have access to the latest version with the most recent servers added.

If you got any further ideas or comments, please let me know in the comments section below.

June 2, 2010 Posted by Jan Egil Ring | Active Directory management, RSAT, Remote Desktop Services, Remote Management, Scripting, Windows 7, Windows PowerShell, Windows Server 2008 R2 | 5 Comments

Enable and configure Windows PowerShell Remoting using Group Policy

As you may know, Windows PowerShell 2.0 introduced a new remoting feature, allowing for remote management of computers.

While this feature can be enabled manually (or scripted) with the PowerShell 2.0 cmdlet Enable-PSRemoting, I would recommend using Group Policy whenever possible. This guide will show you how this can be accomplished for Windows Vista, Windows Server 2008 and above. For Windows XP and Windows Server 2003, running Enable-PSRemoting in a PowerShell startup script would be the best approach.

Windows PowerShell 2.0 and WinRM 2.0 shipped with Windows 7 and Windows Server 2008 R2. To take advantage of Windows PowerShell Remoting, both of these are required on the downlevel operating systems Windows XP, Windows Server 2003, Windows Vista and Windows Server 2008. Both Windows PowerShell 2.0 and WinRM 2.0 are available for download here, as part of the Windows Management Framework (Windows PowerShell 2.0, WinRM 2.0, and BITS 4.0). To deploy this update to downlevel operating systems I would recommend to use WSUS, which are described in detail in this blog post by Kurt Roggen.

Group Policy Configuration

Open the Group Policy Management Console from a domain-joined Windows 7 or Windows Server 2008 R2 computer.

Create or use an existing Group Policy Object, open it, and navigate to Computer Configuration->Policies->Administrative templates->Windows Components

Here you will find the available Group Policy settings for Windows PowerShell, WinRM and Windows Remote Shell:

image

To enable PowerShell Remoting, the only setting we need to configure are found under “WinRM Service”, named “Allow automatic configuration of listeners”:

image

Enable this policy, and configure the IPv4 and IPv6 addresses to listen on. To configure WinRM to listen on all addresses, simply use *.

No other settings need to be configured, however, I`ve provided screenshots of the other settings so you can see what`s available:

image

image

image

image

There is one more thing to configure though; the Windows Firewall.

You need to create a new Inbound Rule under Computer Configuration->Policies->Windows Settings->Windows Firewall with Advanced Security->Windows Firewall with Advanced Security->Inbound Rules:

image

The WinRM port numbers are predefined as “Windows Remote Management”:

image

With WinRM 2.0, the default http listener port changed from TCP 80 to TCP 5985. The old port number are a part of the predefined scope for compatibility reasons, and may be excluded if you don`t have any legacy WinRM 1.1 listeners.

image

image

When the rule are created, you may choose to make further restrictions, i.e. to only allow the IP addresses of your management subnet, or perhaps some specific user groups:

image

Now that the firewall rule are configured, we are done with the minimal configuration to enable PowerShell Remoting using Group Policy.

image

On a computer affected by the newly configured Group Policy Object, run gpupdate and see if the settings were applied:

image

As you can see, the listener indicates “Source*”GPO”, meaning it was configured from a Group Policy Object.

When the GPO have been applied to all the affected computers you are ready to test the configuration.

Here is a sample usage of PowerShell Remoting combined with the Active Directory-module for Windows PowerShell:

image

The example are saving all computer objects in the Domain Controller Organization Unit in a variable. Then, a foreach-loop are invoking a scriptblock, returning the status of the Netlogon-service on all of the Domain Controllers.

Summary

We`ve now had a look on how to enable and configure PowerShell Remoting using Group Policy.
There are an incredible number of opportunities opening up with the new Remoting feature in Windows PowerShell 2.0. For a complete walkthrough on how you can use this new feature, I would like to recommend the excellent Administrator’s Guide to Windows PowerShell Remoting written by Dr. Tobias Weltner, Aleksandar Nikolic and Richard Giles.

March 4, 2010 Posted by Jan Egil Ring | Active Directory management, Deployment, Group Policy, Scripting, Windows 7, Windows PowerShell, Windows Server 2003 R2, Windows Server 2008, Windows Server 2008 R2, Windows Vista, Windows XP | , , | 1 Comment

Articles published on ITPro.no

Recently I`ve published a few articles on the Norwegian website ITPro.no which might be of interest for the Norwegian readers:

Administrasjon av Active Directory med Windows PowerShell

Hva er nytt i Microsoft Exchange 2010

Konfigurer Single Sign-On mot Remote Desktop Services

February 12, 2010 Posted by Jan Egil Ring | Active Directory management, Exchange Server 2010, Remote Desktop Services, Terminal Services, Windows PowerShell | 1 Comment

Validate SPN mappings using Windows PowerShell

 

What is a SPN mapping?

A Service Principal Name (SPN) mapping allows a service running on an Active Directory computer to be associated with a domain account that are responsible for the management of the service. This allows the use of mutual Kerberos authentication, and an account defined in a SPN mapping are able to request Kerberos tickets on the requesting user`s behalf. Examples of services that uses Kerberos and SPN mappings include SQL Servers, web servers, LDAP servers, Exchange servers and so on.

Validation of SPN mappings

A SPN mapping must be unique within an Active Directory domain, and duplicate mappings will result in problems for the involved services.

While the command line tool setspn.exe, which are used for managing SPN mappings also can be used for queries, I wanted to use Windows PowerShell to accomplish this. I`ve put together a script module with two functions:
Resolve-SPN – Resolves the provided SPN mapping
Resolve-AllDuplicateDomainSPNs – Resolves all SPN mappings in the domain and reports duplicate mappings

The script module are available on the TechNet Script Center Gallery, click here for the direct link.

Save the script module as a psm1-file in the following directory: %userprofile%\Documents\WindowsPowerShell\Modules\SPNValidation
 
You need to manually create the 3 subfolders under %userprofile%\Documents if they doesn`t exist.

When done, start Windows PowerShell and type the following command:

image

You should now see the SPNValidation module.
Import the module with the Import-Module cmdlet:

image

Resolve-AllDuplicateDomainSPNs can be executed without any parameters:

image

Resolve-SPN has one mandatory parameter: –SPN
Example usage:

image

Note that the PowerShell Active Directory module for Windows
Server 2008 R2 are required, because the Get-ADObject cmdlet are used in one of the script module`s functions.
The PowerShell Active Directory module are also available in Remote Server Administration Tools (RSAT) for Windows 7.

January 28, 2010 Posted by Jan Egil Ring | Active Directory management, Scripting, Windows PowerShell | , , | Leave a Comment

Automate Group Policy Preferences printer-management using Windows PowerShell

I`ve written a couple of blog posts earlier on Group Policy Preferences and printer deployment using Group Policy.

Using Group Policy Preferences is a very flexible way to deploy printer connections. This is also very manageable in smaller environments. What if you got hundreds, or even thousands of printer connections you need to deploy? Do you want to sit down and make several thousands of mouse clicks to accomplish the task? There are better alternatives!

Based on SDM Software`s Group Policy Automation Engine, I`ve created a script module to handle this. The script module are available from this link.

Save the script module as a psm1-file in the following directory: %userprofile%\Documents\WindowsPowerShell\Modules\GPPreferencesPrinters
You need to manually create the 3 subfolders under %userprofile%\Documents if they doesn`t exist.

When done, start Windows PowerShell and type the following command:

image

You should now see the GPPreferencesPrinters module.
Import the module with the Import-Module cmdlet:

image

As you can see there are two functions in addition to SDM Software`s cmdlet: Add-GPPreferencesPrinter and Get-GPPreferencesPrinter.

Example 1:

image

Example 2:

If you got the printers listed in an Excel spreadsheet, save the document in csv-format:

image

The csv-file may be used like this to import the printer connections:

image

image

Additional functions and parameters will later be added to the script module, i.e. Remove-GPPreferencesPrinter and Item-Level Targeting. Note that example usage for Item-Level Targeting are provided in the Group Policy Automation Engine User Manual.

January 18, 2010 Posted by Jan Egil Ring | Active Directory management, Deployment, Group Policy, Print management, Scripting, Windows PowerShell | 1 Comment

Active Directory group membership modifications report

Based on customer needs I`ve created a Windows PowerShell script to report Active Directory group membership modifications. The script are uploaded to PoshCode and available from here.

In Windows 2000 Server and Windows Server 2003, the following security event IDs were valid for group membership changes:

Scope Member added Member removed
Local 636 637
Global 632 633
Universal 660 661

In Windows Server 2008 and Windows Server 2008 R2 the security event IDs changed:

Scope Member added Member removed
Local 4732 4733
Global 4728 4729
Universal 4756 4757

Source for 2000/2003 event IDs.
Source for 2008/2008 R2 event IDs.

Group membership auditing are enabled by default from Windows 2000 Server to Windows Server 2008 R2, so there are no need change any auditing settings to accomplish this.
I`ve added event ID`s for both 2000/2003 and 2008/2008 R2 to the script to cover all event ID`s currently available.
Group membership changes are logged to the Security eventlog on the domain controller the modification was run against. Because of this the script are set up to get all domain controllers in the current domain and loop through the security eventlog on each of them, searching for the relevant event ID`s described in the table above.

The script are based on Alan Renouf`s Daily Report script for PowerCLI.

The “isWithin”-function are taken from Jeffrey Snover`s blog-post regarding DateTime Utility Functions.

Preview of the HTML-report the script will generate:

image

A tip would be to run the script as a scheduled task e.g. once a day, and store the file in a central location.

For those of you interested in Active Directory auditing I would recommend you to have a look at the AD DS Auditing Step-by-Step Guide on Microsoft TechNet.
Personally I think the new “directory service changes” category are very useful, which allows us to see both the old and new values on modified Active Directory user objects.

October 11, 2009 Posted by Jan Egil Ring | Active Directory management, Auditing, Scripting, Windows PowerShell | | 7 Comments

Generate random passwords for Active Directory users v2

A litte while ago I posted a script to generate random passwords for each user in a specified OU in an Active Directory environment.

Now I`ve just posted another version of this script on PoshCode.

This script are intended for another scenario:
Power users with delegated permissions to reset password for specified Organizational Units. The power users get this script available as a published application in Remote Desktop Services.

September 29, 2009 Posted by Jan Egil Ring | Active Directory management, Scripting, Windows PowerShell | , | Leave a Comment

Replmon.exe not included in Windows Server 2008/2008 R2

A lot of administrators are used to check their Active Directory replication status using replmon.exe which is a part of the Windows Server 2003 Support tools.
Today I stumbled across the need to use replmon.exe on a domain controller running Windows Server 2008, and was unable to find it.

It turns out that that this utility is not included in Windows Server 2008/2008 R2.

According to a comment from a team member from the Microsoft Directory Services Team, this is the explanation:

“Unfortunately, replmon did not survive the transition to Win2008. It was actually developed by MS support, not the product group (along with many other support tools/resource kit tools), and without an actual owner to service the tool years later, it was a casualty. I don’t see why it wouldn’t work on 2008 though…”

I wouldn`t recommend using unsupported tools on Windows Server 2008/2008 R2, so the advice would be to either use repadmin.exe on 2008/2008 R2, or to use replmon.exe from a Windows Server 2003 server.

You can find the command reference for repadmin.exe in Windows Server 2008/2008 R2 here.

A few examples:

repadmin.exe /showrepl shows the replication-status for the domain controller the tool are being run from.

repadmin.exe /showrepl servername shows the replication-status for the domain controller with the provided servername,

repadmin.exe /queue shows the replication-queue for the domain controller the tool are being run from.

repadmin.exe /queue servername shows the replication-queue for the domain controller with the provided servername,

repadmin.exe /replsummary shows a brief summary of the replication status.

I also checked if there are any PowerShell cmdlets for checking replication status in Windows Server 2008 R2, but it`s not. Hopefully this will be implemented some time in the future.

PS: I did test installing the Windows Server 2003 Support tools on a Windows Server 2008 domain controller in a lab environment, and it does work.

September 18, 2009 Posted by Jan Egil Ring | Active Directory management, Windows Server 2008, Windows Server 2008 R2 | , | 2 Comments