Virtualization, High Performance Computing, Healthcare IT, Enterprise Computing


You are currently browsing the archive for the PowerShell category.

If you need to add a domain service account to the local Administrators group on a list of computers, this simple PowerShell script will take file with a list of computer names ( one per line) and add the user to the local Administrators group on all of them.


Powershell to Bulk Add a User to Local Admin on Multiple Computers

Powershell to Bulk Add a User to Local Admin on Multiple Computers

The script is below, you must change the string MYDOMAINHERE to whatever your domain is.

function ListAdministrators($Group)
  $members= $Group.psbase.invoke("Members") | %{$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}

function Ping-Server {
   $pingresult = Get-WmiObject Win32_PingStatus -Filter  "Address='$srv'"
   if($pingresult.StatusCode -eq 0) {$true} else {$false}

if ($args.Length -ne 2) {
 Write-Host "`tUsage: "
 Write-Host "`t`t.\AddToLocalAdmin.ps1 < group or user > <file of machines>"
 Write-Host "`t`tExample: .\AddToLocalAdmin.ps1 FooBarGroup c:\temp\mymachines.txt"

#Your domain, change this
$domain = "MYDOMAINHERE"

#Get the user to add
$username = $args[0]

#File to read computer list from
$strComputers = Get-content $args[1]

foreach ($strComputer in $strComputers)

  if (Ping-Server($strComputer)) { 

      $computer = [ADSI]("WinNT://" + $strComputer + ",computer")
      $Group = $computer.psbase.children.find("administrators")
      # This will list what’s currently in Administrator Group so you can verify the result
      write-host -foregroundcolor green "====== $strComputer BEFORE ====="
      ListAdministrators $Group
      write-host -foregroundcolor green "====== BEFORE ====="

      # Even though we are adding the AD account
      # It is being added to the local computer and so we will need to use WinNT: provider 

      $Group.Add("WinNT://" + $domain + "/" + $username) 

      write-host -foregroundcolor green "====== $strComputer AFTER ====="
      ListAdministrators $Group
      write-host -foregroundcolor green "====== AFTER ====="

      write-host -foregroundcolor red "$strComputer is not pingable"


There is an interesting webpage at the NY Times that allows you to play rock-paper-scissors against a computer that uses 200,000 past rounds against humans in an attempt to defeat you.

A truly random game would be the best offense, since the computer is programmed to reply with a non-random throw based on what a human would do. I thought this would be a fun way to show how you can use PowerShell to create a simple script to create a randomized set of throws to play:

$hand = "rock", "paper", "scissors"
$rand = New-Object system.random
#Just keep repeating this line to get the next throw

The result after 41 rounds was a PowerShell Win!

Result of PowerShell vs Rock-Paper-Scissors

Result of PowerShell vs Rock-Paper-Scissors


NetApp has released a fantastic PowerShell kit to automate operations with their filers.

To get started, download the DataOntap.zip and install.ps1 from the NetApp NOW site, and place them in c:\temp\ on a Windows box with PowerShell ( I am using 2008 R2 with PowerShell Version 2 )

Start PowerShell, and type the following:

set-executionpolicy remotesigned
cd c:\temp\

after that, start PowerShell again and type

     Get-Module -listavailable

to make sure you see DataONTAP installed.

Now you can type

Import-Module DataONTAP

To access the DataONTAP cmdlets in your session. You will need to do this each time you start PowerShell, or you can add the above command to your PowerShell profile to automatically load them.

To see help and examples, you can use the following command:


For detailed help on a cmdlet, use get-help as you normally would with PowerShell:

Get-Help Connect-NaController –full

There are MANY great cmdlets available to automate common NetApp administration tasks.

A great example is a script mixing both NetApp and VMware PowerShell automation by Jase McCarty here which automatically provisions and mounts storage on all ESX hosts.

I modified Jase’s script slightly to work with PowerShell 2.0 and to use root access instead of AD credentials. This script must be ran from VMware PowerCLI to work:

# Add the  DATA ONTAP Module
Import-module DataONTAP
# Set my variables. Change for your site
$vCenter = ""
$Filer = ""
$aggr = "aggrx"
$newvol = "volx"
$narootpasswd = "netapprootpasshere"

#Connect to NetApp as root
$password = ConvertTo-SecureString $narootpasswd -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "root",$password

Connect-NaController $Filer -Credential $cred

# Create a new 6GB volume
New-NaVol $newvol $aggr 6g

# Set some options for the new volume
Set-NaVolOption $newvol no_atime_update yes
Set-NaVolOption $newvol fractional_reserve 0

# Set the SnapShot Reserve to 0
Set-NaSnapshotreserve $newvol 0
Set-NaSnapshotschedule $newvol -Weeks 0 -Days 0 -Hours 0

# Add an NFS export
Add-NaNfsExport /vol/$newvol -Persistent -ReadWrite all-hosts -NoSuid -SecurityFlavors sys,krb5

# Get all the vSphere Hosts and add the NFS export. This requires VMware PowerCLI

# Connect to vCenter
Connect-VIServer $vCenter

$Hosts = Get-VMHost
ForEach ($h in $Hosts)
New-Datastore -Nfs -VMHost $h.Name -NAME $newvol -Path /vol/$newvol -NfsHost $Filer;

Recently a customer noted that many of their VMs were still showing up on an old datastore after doing a storage vMotion to a new datastore. Browsing the actual datastore showed the VM was not there, but the VIC continued to report it was.

The issue was the customer had Storage vMotioned with ISO images connected, which you should not do. The simple fix was to disconnect all the ISO images from those VMs. This is easy through the VIC GUI, but to automate it and make sure none were missed we used Power CLI:

Get-VM  | ForEach ( $_ ) { Get-CDDrive $_ | Where { $_.IsoPath.Length -gt 0 -OR $_.HostDevice.Length -gt 0 } | Set-CDDrive -NoMedia -Confirm:$False }

Or to just do this for a particular datastore:

Get-VM  -DataStore mydatastore | ForEach ( $_ ) { Get-CDDrive $_ | Where { $_.IsoPath.Length -gt 0 -OR $_.HostDevice.Length -gt 0 } | Set-CDDrive -NoMedia -Confirm:$False }

We love PowerShell at HiperLogic, because we use it to automate just about everything.

Veeam Backup has PowerShell integration, and this post is about creating a small script to meet a user requirement to get a list of VM’s in a backup job called “mytestjob”. The customer wanted to integrate this information into another program via powershell glue.

To run this code, run the following from the powershell console:

add-pssnapin "VeeamPSSnapIn"
$job = Get-VBRJob -name "mytestjob"
$job.GetObjectsInJob() | foreach { $_.Location }

One other interesting easter egg of things to come, run this powershell line

 Get-VBRJob |get-member |select-string "HyperV"

To configure syslog on ESXi to forward to a central logger, you can just use the VIC and go to Configuration->Advanced Setting->Syslog ->Remote.

To do this on a bunch of ESXi servers, you will want to do this programatically using either the vSphere vCLI (Perl) or PowerCLI (Power Shell). Get these tools free at http://www.vmware.com/go/sysadmintools.

In the vCLI :

vicfg-syslog.pl –p 514 –s < IP of your syslog server > –server < IP of your ESXi host>

Then enter root username, and root password of your ESXi host.

In Power Shell:

Set-VMHostSysLogServer -SysLogServerPort 514 –SysLogServer < IP of your syslog sever > -VMHost < IP of your ESXi host >

Update 6/23/2010 : See this website for caveat with syslog on ESXi http://www.virtuallyghetto.com/2010/06/esxi-syslog-caveat.html


PowerShell is a fantastic way to automate just about everything in a Windows and VMware environment, enabling your IT department to do with more with less, which is the must-have skill of today.

Unix aficionados switching to PowerShell may at first struggle with how to recreate their favorite functionality from Unix land, like grep and awk. PowerShell can do all the powerful string manipulations that awk/sed/perl can do, just in a different manner.

For example, a typical Linux scenario using awk and grep might be:

grep “somestring” foo.txt | awk ‘{print $2}’

The powershell equivalent is below:

select-string -pattern “somestring” foo.txt | foreach { $_.ToString().split(” “)[2] }

The very excellent PowerShell Community Extensions also provide some nice items you may desire from Unix/Linux toolbox.

Tags: ,

I found that WinRM limits the number of concurrent shells while developing some PowerShell tools that connect around to a bunch servers in parallel. You may get an error like:

“Connecting to remote server failed with the following error message : The WS-Management service cannot process the request. This user is allowed a maximum number of 4 concurrent shells, which has been exceeded. Close existing shells or raise the quota for this user.”

This is how to configure and override the default of 5:

PSH>winrm quickconfig
PSH>winrm get winrm/config
PSH>winrm set winrm/config/winrs `@`{MaxShellsPerUser=`”50`”`}


© 2006-2010 HiperLogic, LLC.  |  Serving the Ann Arbor, Southeast Michigan, and Ohio region  |  (888)-268-3930  |