I’ve had a need to reset password’s for accounts on an automated basis more so recently than before, so not knowing where to start, I took a look around the internet and found some pieces of code here and there that would start to fulfill my needs.

Basically, I was setting up an 802.11x authenticated wireless network, and had a requirement to automate the password change of a RADIUS authenticated Guest account that was sat in a locked down OU in the domain. This then needed to be random, secure and e-mailed to a public folder so that the employees could give their guests access to the guest network. The script just needs to be added to a scheduled task to run monthly. So I eventually ended up with this:

import-module activedirectory

[int] $len = 12
[string] $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
$bytes = new-object "System.Byte[]" $len
$rng = new-object System.Security.Cryptography.RNGCryptoServiceProvider
$result = ""
for( $i=0; $i -lt $len; $i++ )
$result += $chars[ $bytes[$i] % $chars.Length ] 

$securestring = ConvertTo-securestring $result -asplaintext -force

get-aduser "GuestUserName" | set-adaccountpassword -newpassword $securestring

$month= get-date -format MMMM

###Sets the mail values
$FromAddress = "Wireless_Guest@some-domain.com"
$ToAddress = "public-folder@some-domain.com"
$MessageSubject = "New Wireless Guest Details for $month"
$MessageBody = "Username: GuestUserName          Password: $result"
$SendingServer = "my.mail-relay.com"

###Create the mail message and add the statistics text file as an attachment
$SMTPMessage = New-Object System.Net.Mail.MailMessage $FromAddress, $ToAddress, $MessageSubject, $MessageBody

###Send the message
$SMTPClient = New-Object System.Net.Mail.SMTPClient $SendingServer

In short:

Line 3: Specifies the number of characters in the generated password.
Line 4: The characters that can be used to generate the password.
Line 17: Reset’s the password on the AD account.
Line 19: Generates the month in long format to add to the e-mail Subject.
Line 22-26: Variables used for sending the e-mail.
Line 29: Generates the e-mail.
Lines 32 & 33: Sends the e-mail.

Jan 19

Today I needed to find a way to gather a list of the IP’s for all of our VM’s so I came up with this little one-liner, so thought I’d share it with you:

get-vm | select Name,@{N="IP Address";E={@($_.guest.IPAddress[0])}} |
         out-file c:\VM_IP_Addresses.csv

It’ll get all of the VM’s in the environment, and then list out the first IP address for each one. If you have multiple IP’s on some hosts, then remove the “[0]” section in the above and it’ll list all of them. The output will be tab delimited text rather than comma separated.

At last!!! VMware Labs have released a package to add VDS functions into PowerCLI!

It is a Fling though that was only released yesterday, so it’s not going to have any official support from VMware, and currently only supports Windows XP, 2003 and 2008 (no mention of 2008 R2 here). You also need to be running PowerCLI 4.1.1 or later.

You can import the snap-ins like this:

Add-PSSnapin VMware.VimAutomation.VdsComponent

And list the cmdlets like this:

Get-Command –Module VMware.VimAutomation.VdsComponent

You can download them from here:

Vmware Labs PowerCLI VDS Download

And you can get some more information from Virtu-Al.net here:


This morning I’ve been troubleshooting an Exchange public folder related issue that had me baffled for a little while.

Users could send e-mails to a public folder internally, but any external e-mails wouldn’t arrive in the folder. After running through message tracking I found the following error in the tracking logs:

550 5.2.0 STOREDRV.Deliver: The Microsoft Exchange Information Store service reported an error. The following information should help identify the cause of this error: “MapiExceptionNotAuthorized:”…

Knowing that internal users could e-mail the public folder, and knowing that the e-mails were reaching the Exchange server meant that I had to be dealing with a permissions based issue. When I looked at the public folder’s MAPI permissions using Powershell (get-publicfolderclientpermission is the cmdlet for that one) I could see that the folder was set to “Anonymous: None”. This means that anonymous senders don’t have rights to create a new item in the public folder, and so the 550 5.2.0 message is logged.

To get around this issue, you need to add at least the “CreateItems” access right for the Anonymous user. You can do this within Outlook looking at the permissions, or, in PowerShell as follows:

add-publicfolderclientpermission -identity "\PathTo\PublicFolder" -accessright createitems

To check this afterwards you can perform the following script:

get-publicfolderclientpermission -identity "\PathTo\PublicFolder" | where {$_.User -match "Anonymous"} | fl

Sep 16

Odd problem today with the XenApp client, erroring each time I tried to login to any published app:

Citrix OP Error 2320


After a fair bit of digging, I found a registry key call “ClientHostedApps” here:

HKEY_CURRENT_USER\Software\Citrix\ICA Client\Engine\Lockdown Profiles\All Regions\Lockdown\Virtual Channels\Control

Simply removing this key and re-opening the client was all it took for the client to operate and the apps to start working again.

OK, this is something I’ve been using for a while and wanted to share with you, as I’ve been asked for it a couple of times now.

I’ve got a pair of Cisco ASA’s at the perimeter of our network, and I needed a way some time ago to edit it’s configuration in a scripted manner, so, I started looking at PowerShell and SSH connections, and this didn’t get me anywhere, so I started to look at PLINK.exe. PLINK is almost a spin-off from PuTTY, a free remote connection tool that supports SSH. PLINK is scriptable, in that you can pass it a text file, and it’ll run each line of that file as seperate commands. Simply enough, the powershell script below will echo out to a file any commands you need, then start PLINK and run the code. If it’s a system that you’ve not connected to before, and don’t have the key saved in your registry, you’ll be prompted to accept it.

$ASApw = "MyPassword"
$ASAIP = "MyASAIPAddress"
$ASAUser = "MySSHUserName"
$ASAEnablepw = $ASApw

#Modifies the ASA firewall
#Starts by writing a "commands" file#
echo en >>unicode.txt
echo $ASAEnablepw >>unicode.txt
echo "conf t" >>unicode.txt
echo "show run access-group"
echo exit >>unicode.txt
echo exit >>unicode.txt

#Converts the file to ASCII format (separate file)#
$lines = gc "unicode.txt"
$lines | out-file -encoding Ascii -filepath commands.txt

#Using the command file and plink.exe connects and runs the commands #
./plink.exe -ssh -l $ASAUser -pw $ASApw $ASAIP -m commands.txt

#removes the files it created earlier#
del unicode.txt
del commands.txt

In the above example, the ASA will be asked to show it’s running config’s access-group configuration. You’ll need to modify the echo lines to get this to perform other actions (I use this script to modify static mapping entries and access-lists for example). You’ll also need to modify “$ASAIP”,”$ASAUSer” and “$ASApw” with your IP address, SSH Username and SSH password. The script assumes that the enable password matches this, but if not, edit the “$ASAEnablepw”, and add your enable password there. If you don’t like storing password this way (I don’t particularly) then you can always change these to “read-host” to request the entry from the Powershell command line.

After all the hassle I’ve had with snapshots recently it was time to finalise this script. It’ll find all of the snapshots in your environment, based on age, and then e-mails a nice list to you.

param ($Age = 0)
$outfile = "c:\snaps.csv"
$output="VM Name,Snapshot Name,Snapshot Size,Creation Date"+"`n"+"`n"
$vcenter = "servername"

Connect-VIServer $vcenter

$snapshotlist = get-snapshot -VM (get-vm)
Write-Host -ForegroundColor Red "Matching Snapshots Found: "

foreach ($snap in $snapshotlist) {
     if ($snap.Created -lt (Get-Date).AddDays(-$Age)) {
          Write-Host "VM: " $snap.VM "Name: " $snap.Name "Size: " $snap.SizeMB "Created: " $snap.created
          $output = $output + $snap.VM + "," + $snap.Name + "," + $snap.SizeMB + "," + $snap.created + "`n"

disconnect-viserver * -force:$true -confirm:$false

Out-file $output $outfile

#Sets the mail values
$FromAddress = &quot;<;a href=&quot;mailto:Snapshots@domain.com&quot;>;snapshots@domain.com<;/a>;&quot;
$ToAddress = &quot;<;a href=&quot;mailto:recipient@domain.com&quot;>;recipient@domain.com<;/a>;&quot;
$MessageSubject = &quot;Snapshot Report&quot;
$SendingServer = &quot;mail_relay.domain.com&quot;
$MessageBody = $output

#Create the mail message
$SMTPMessage = New-Object System.Net.Mail.MailMessage $FromAddress, $ToAddress, $MessageSubject, $MessageBody

#Send the message
$SMTPClient = New-Object System.Net.Mail.SMTPClient $SendingServer

Modify these settings as required for your environment/needs:

$FromAddress = “snapshots@domain.com”
$ToAddress = “recipient@domain.com”
$MessageSubject = “Snapshot Report”
$SendingServer = “mail_relay.domain.com”
$outfile = “c:\snaps.csv”
$vcenter = “servername”

By default, the script will collect info about all snapshots. If you want to modify that list, and only have snapshots created more than 7 days ago, just call the script with the “-age” parameter, and you’ll only get a list of VM’s that have been around for longer than that time.

Full Error:

File <unspecified filename> is larger than the maximum size supported by datastore ‘<unspecified datastore>

I’ve been coming up against this issue for the last few days whilst installing some backup software for one of our customers. It’s highly frustrating and I couldn’t figure out why this was even happening. The data stores that this particular VM was running on had plenty of free disk space, and none of the disks exceeded the file size maximum for the block size on those disks.

What I didn’t know was, quite simply, that a VM cannot snapshot if it’s configuration file is stored on a data store with a smaller block size than one of it’s virtual hard disks. Now, I presume, that this is only the case if the virtual disk size is larger than the supported size of a file on the configuration files data store.

So, if you come accross this problem, just storage vMotion the configuration file to a data store with a larger block size, or at least to a datastore with the same size block size as your largest virtual disks’ data store. Run another snapshot, and “Hey Presto!” it should snapshot correctly.

Onswipe added to Spug.co.uk

posted by Dan Hayward
Aug 25

Just a quick update for all you iPad users out there, I’ve now added OnSwipe to spug.co.uk which makes browsing the site via iPad a heck of a lot easier – and it looks good too!

For anyone who has an iPad and wants to take a look, just head to the main http://www.spug.co.uk page, and you’ll see the OnSwipe version of the site.

%d bloggers like this: