Archive for the ‘powershell’ Tag

Powershell Script to Locate Windows Services Running as Domain users

Ever had to change a domain administrator’s password and had the sinking feeling that some bozo had setup a Windows service to run as that user.   If you only have a couple servers it isn’t that big a deal to check each manually, but if you have a lot it can be a problem.  I’ve seen a lot of admins just use the scream test to figure out what broke, but sometimes it isn’t obvious until the server is rebooted.  We run into this situation frequently as we take over new clients.

Recently we had to make a change for a customer with 50+ Windows servers and I knew the account had been used for services. I just didn’t know where.  So I built the below powershell script.  I definitely owe a few people props as I used a number of different websites to figure out the WMI piece. Unfortunately, it has been too long since I remember who.  But the next best thing is to put this script out there for other to use.  So I have posted the script and a readme file to GitHub (a new experience for me, but way better than how I published my scripts previously).

Hope this helps out.  This is provided “as-is” and while I’ve used in several environments I can’t guarantee it will work everywhere.  Feel free to leave respectful comments.


PowerCLI Script to automatically setup vCenter Alarm Email Notification.

After manually setting up email Alarm notifications for numerous vSphere deployments I decided it was time to harness PowerCLI and automate the process.

I found numerous examples of people who had already done this before me, so I figured it would be pretty easy.  It looks like the guys at built a script that several others adapted. VirtuallyMikeBrown had created a script for vSphere 4.1, but it wasn’t updated for vSphere 5 and only had a single email address.  Justin at Justin’s IT Blog had created a script that allowed three email addresses, but it couldn’t handle 4 or 2 or just 1 without editing the script or using dummy addresses.   And both of these scripts used a variable for each vCenter Alarm which meant if you added or removed an alarm you had to make multiple edits throughout the script.

So I decided I wanted my script to do the following:

  • Use arrays for both the alarms and email addresses to make it easier to add and remove entries.
  • Use a foreach loop to work through the alarms.
  • Have different classification or priorities for alarms so that some would notify repeatedly and with different frequencies. For example. You might not care if a VM is maxing out it’s CPU, but you definitely want to know if a host is.

These additional requirements took “easy” and turned it into a frustrating half-day, but I feel pretty good about the result.

Some notes about the script:

  • The $user, $pass and $vCenterServer variables need to be edited to be correct for your environment.
  • This currently sets up email alerts for almost every single default alarm in vCenter (based on 5.0).  This is undoubtedly overkill and you’ll likely want to remove some from the lists.
  • In the current setup this script takes a while to run through all the alarms.  It took about 10 minutes for me.  But that’s still a lot faster than doing it manually.
  • If you add or remove an alarm from the list make sure the following syntax is maintained:
    • Alarm names should be in double-quotes (“)
    • Alarms should be separated by commas (,)
    • Back-ticks (`) are used to continue a breakup the single line of alarm names into multiple lines for readability.   All alarms should have a back-tick at the end of the line except the last in the array.
  • If you want to add or remove email addresses make sure they too are in double-quotes, separated by commas with no spaces.
  • If you want to change the frequency of the repeating alerts just change the second number in the  “-ActionRepeatMinutes (60 * 24)” section.

This script is provided with no guarantees or warranties.  Use at your own risk.  Comments and feedback are welcome.

*********Updated 10/29/2012*******************

VMware decided to rename some alarms in 5.1 so I’ve now have two versions of the script.

vSphere 5.0 Script

vSphere 5.1 Script

Update 3/18/2015

Today I learned two things to be aware of:

  1. If the password contains special characters (see below) then those characters need to be escaped by prefixing the back tick or grave accent character (`).  So the password P@$$word would need to be entered as “P@`$`$word”
    1. Special characters in PowerShell are $ (  ) * + . [  ] ? \ / ^ { } |
  2. Since the vCenter Server Appliance uses Sendmail the delimiter between multiple email addresses has been changed from a semicolon to a comma. Because the PowerCLI command is the one formatting the entry with the semi-colon I’m not sure yet how to fix this.  (Thanks to AdminAfterWork for pointing this out)

Office 365 PowerShell Script to Set PasswordNeverExpires for All Members of Group

I had a need to set all members of a group so that their Office 365 (aka Microsoft Online) passwords never expire.  Didn’t take too long but I though it was worth sharing.  I also added output to show the setting was changed.  This could certainly be prettier but it is what it is.


  • This requires you to have the Office 365 Powershell cmdlets installed, which also required the Online Services Sign-in Agent to work. See this article for instructions.
  • You need admin credentials to your Office 365 account.
  • The script references the ObjectID of the Office 365 Group whose members you wish to change.  To get this you need to connect to Office 365 and use the Get-MsolGroup command. Below is a code snippet showing how.
import-module MSOnline

Output will look something like below.


The below would need to be saved as a .ps1 file.  The Object ID (shown in red #’s below) would need to be changed to match that of the desired group

import-module MSOnline
### Get All the Members of the Group
$agents=Get-MsolGroupMember -GroupObjectId  ########-####-####-####-############
### Set PasswordNeverExpires to true for all members of the group.
Foreach ($agent in $agents ) {
Set-MsolUser -ObjectID $agent.ObjectID -PasswordNeverExpires $true
$postChangeAgent = Get-MsolUser -ObjectID $agent.ObjectID
Write-Host “User: ” $postChangeAgent.UserPrincipalName “PasswordNeverExpires:” $postChangeAgent.PasswordNeverExpires

Note: The line beginning with “Write Host” wraps. The end of that line in your script is the $postChangeAgent.PasswordNeverExpires

Cudos and References

Thanks to JoshT_MSFT @ the Office365 Technical Blog for the following article which pointed me in the correct direction.

Set Owner with PowerShell: “The security identifier is not allowed to be the owner of this object”

I’ve written several PowerShell scripts to help customers adjust permissions to their directory structures when migrating from other file servers(Linux/Samba, Novell OES/Netware, etc).  Part of these scripts includes assigning ownership for the user.  While this tends to take a long time quotas and file reporting are worthless if the administrator that copied everything is assigned as the owner.

Recently I tried to adapt one of these scripts for a customer, but when I ran it it failed with the error: “The security identifier is not allowed to be the owner of this object”

A quick internet search found lots of people saying basically this can’t be done with PowerShell.  What!!! I know for a fact these scripts had worked before.  What’s the deal?   After a lot of testing and beating my head against the wall I figure out I was trying to do something different.  Previously I had run my scripts against the UNC path (eg. \\servername\share\directory), but this time I was trying to run it on a local directory using the drive path (E:\Share\Directory).

Could it be that simple? Yes.  I ran the command again using the UNC path and the script worked as it did before.

Here is an example script to set the owner of a directory or file to test the above:

function pathPrompt {

$tempPath = $null
$tempPath = Read-Host ‘Please enter the path of thedirectory (e.g. “\\file\vol1\users\example”‘
return $tempPath

$ID = new-object System.Security.Principal.NTAccount($domain, $username)

$path = pathPrompt

write-host $path

$acl = get-acl $path
set-acl -path $path -aclObject $acl

Save the above to a file with a .PS1 extension, change the $username and $domain variables, and run it (make sure you set-executionpolicy to unrestricted and PowerShell as administrator). It will prompt for a path. It will then write the path to powershell and then set the owner if it can.

Below is an example of running it against a local path and a UNC path.