Pages

3/28/2011

WSUS Client Troubleshooting - Getting Serious

Tons of good stuff here: wsuswiki.com

I found several VM's that weren't deployed properly (Geez SYSPREP for petes sake!!!!!)

I'm probably just going to run the following on all 400 of them just to be sure:

psexec @list.txt -u administrator -C c:\rereg.bat
Which references the following that must be on c:\ of the machine where the above is run:

@echo off
net stop wuauserv
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" /v AccountDomainSid /f
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" /v PingID /f
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" /v SusClientId /f
REG DELETE "HKLM\Software\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v LastWaitTimeout /f
REG DELETE "HKLM\Software\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v DetectionStartTime /f
REG DELETE "HKLM\Software\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v NextDetectionTime /f
REG DELETE "HKLM\Software\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v AUState /f
net start wuauserv
wuauclt /resetauthorization /detectnow 

Auto Logon

HKEY_LOCAL_MACHINE>SOFTWARE>Microsoft>Windows NT>CurrentVersion>Winlogon
AutoAdminLogon REG_SZ 1
DefaultUserName REG_SZ [userid]
DefaultPassword REG_SZ [password]

WSUS Client Troubleshooting

From Technet

Test all the following from the client machine.
- Check network communications with server
- ping WSUS-Server
- http://WSUS-Server[:port] - should get response - e.g. Under Construction
- http://WSUSServerName/selfupdate/wuident.cab
- Should result in offer to download a file - hit cancel
- if not, go to this URL: Check Self-Update Tree
- Check Automatic Update Client
- Open CMD prompt and type
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate
- Should display something like:
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate
WUServer    REG_SZ  http://WSUSServerName
WUStatusServer      REG_SZ  http://WSUSServerName
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU
- Reset Automatic Update Client
- Open CMD prompt and type wuauclt.exe /resetauthorization /detectnow
- Wait 10 minutes
- Check C:\Windows\WindowsUpdate.log
- Check "All Computers" group on the WSUS Server to see if it appears.

3/27/2011

Powershell: Remove inactive accounts

For every machine account listed in a file, remove machine accounts from all groups and then remove the machine accounts.
$ds = new-object directoryServices.directorySearcher 
 
$names = get-content remove.txt
"------------------------------"
foreach ( $account in $names  ) {
    $account
    $ds.filter = "(&(objectCategory=computer)(objectClass=user)(name=$account))" 
    $dn = $ds.findOne() 
    if ($dn) {
           #remove computer from groups
           $user = [ADSI]$dn.path 
           "  Removed from groups:"
     foreach ($group in $user.memberof)
       {
       $groupDE = [ADSI]"LDAP://$group" 
       "    "+$groupDE
       $groupDE.remove("LDAP://$($user.distinguishedName)")  
       }

     #remove computer account
     $old = $user.distinguishedname -replace ',.*$',''
     $olduser = $old -replace 'CN=',''
     $usr = $($olduser).tolower()
     $usr + " removed from AD"             
     $location = $dn.path -replace "$old,",''
     $ou = [ADSI]$location
     $ou.delete("computer","cn=$usr")
 }#if
"------------------------------"
}#foreach

Powershell: Report Server Group Membership

Create an HTML report of each server in AD and its group memberships.

###########################################################################
#
#    server-group.ps1
#
#    Report group membership for each Windows Server in AD
#
###########################################################################

# Create $list of AD machine accounts for Windows Servers 
$strCategory = "computer" 
$strOS = "Windows*Server*"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry 
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher 
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("OperatingSystem=$strOS")
$colProplist = "dnshostname"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults) { 
    $objComputer = $objResult.Properties;  
    $Server = $objComputer.dnshostname
    $Server = $Server -replace "\s{2,}", ""
    $Server = $Server -replace "\.usa\.DOMAIN\.com", ""
    if ($Server) { $list = $list + $Server } #skip a null value
    }#foreach
 
# Prepare output file
"<HTML>" | out-file server-groups.html
"<HEAD>" | out-file server-groups.html -append
"<TITLE></TITLE>" | out-file server-groups.html -append
"</HEAD>" | out-file server-groups.html -append
'<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">' | out-file server-groups.html -append
"<H1>Servers' Group Membership</H1>" | out-file server-groups.html -append
 
foreach ($target in $list) {
    $ds = new-object directoryServices.directorySearcher 
    $ds.filter = "(&(objectCategory=computer)(objectClass=user)(name=$target))" 
    $dn = $ds.findOne() 
    if ($dn) { #found
        $user = [ADSI]$dn.path 
        $userDE = [ADSI]"LDAP://$($user.distinguishedname)" 
        $user.name
        "<b>" + $user.name + "</b><BR>" | out-file server-groups.html -append
        $groups = $user.memberof
        foreach($group in $groups) {
            $strGroup = $group.split(',')[0]
            $strGroup = $strGroup.split('=')[1] 
            "     "+$strGroup
            "        " + $strGroup + "<BR>" | out-file server-groups.html -append
            }#foreach
        }#if
    }#foreach
"</BODY></HTML>" | out-file server-groups.html -append

###########################################################################

Powershell: Import Group Members

This script will be used to import a file of the same format that I export from the previous post. After using Excel to review and change the listings. I use these group memberships to filter group policy permissions to apply WSUS client settings to servers.

############################################################################
#
# IMPORT-SERVER-GROUP.PS1
#
# Assign servers to WSUS group from CSV file.  
# Note:  removes server from any existing groups that contain WSUS
#
# CSV Format:  (include headings)
#
#  Server, Group
#  SERVER01, WSUS Test Group
#
############################################################################

$list = @(Import-Csv WSUS-TEST.CSV)
$today = get-date

"==========================================================================="
" CHANGE LOG - " + $today

foreach ( $item in $list ) {
 $account = $item.Server;
 $target = $item.Group;

"---------------------------------------------------------------------------"
 "    " + $account

#Find computer object and remove it from groups
 $ds = new-object directoryServices.directorySearcher 
 $ds.filter = "(&(objectCategory=computer)(objectClass=user)(name=$account))" 
 $dn = $ds.findOne() 
 if ($dn) { #found
  #remove computer from groups
  $user = [ADSI]$dn.path 
  "      Removed from groups:"
  foreach ($group in $user.memberof)
   {
   $groupDE = [ADSI]"LDAP://$group" 
   "        "+$group
   if ($strGroup -match "WSUS") {
    $groupDE.remove("LDAP://$($user.distinguishedName)")  
    }#if
   }#foreach
 }#if

$dn=0;

#Find group object and add server to it
 $ds = new-object directoryServices.directorySearcher 
 $ds.filter = "(&(objectClass=Group)(name=$target))" 
 $dn = $ds.findOne() 
 if ($dn) { #found Group
  $group = [ADSI]$dn.path 
  $groupDE = [ADSI]"LDAP://$($group.distinguishedname)" 
  $ds.filter = "(&(objectCategory=computer)(objectClass=user)(name=$account))" 
  $dn = $ds.findOne()
  if ($dn) { #found machine account
   $usr = [ADSI]$dn.path
   $ADuser = [ADSI]"LDAP://$($usr.distinguishedname)"
   "      Added to " + $target
   $groupDE.add("LDAP://$($ADuser.distinguishedName)")  
   }#if
 }#if
}#foreach
"==========================================================================="
############################################################################

Powershell: Export Group Membership

Putting the pieces together
This post pulls together some of my previous fragments into something more specifically useful.

###########################################################################
#
#  server-group.ps1
#
#       Export group membership for each Windows Server in AD
#              if the group name contains WSUS
#
###########################################################################

#delete output file if it exists
if ( test-path wsus-server-groups.csv ) { remove-item wsus-server-groups.csv }

# Create $list of AD machine accounts for Windows Servers 
$strCategory = "computer" 
$strOS = "Windows*Server*"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry 
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher 
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("OperatingSystem=$strOS")
$colProplist = "dnshostname"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults) { 
    $objComputer = $objResult.Properties;  
    $Server = $objComputer.dnshostname
    $Server = $Server -replace "\s{2,}", ""
    $Server = $Server -replace "\.USA\.DOMAIN\.COM", ""
    if ($Server) { $list = $list + $Server } #skip a null value
    }#foreach
"Server, Group" | out-file -encoding ASCII  wsus-server-groups.csv # output headings
foreach ($target in $list) {
    $ds = new-object directoryServices.directorySearcher 
    $ds.filter = "(&(objectCategory=computer)(objectClass=user)(name=$target))" 
    $dn = $ds.findOne() 
    if ($dn) { #found
       $user = [ADSI]$dn.path 
       $userDE = [ADSI]"LDAP://$($user.distinguishedname)" 
       $user.name
       $groups = $user.memberof
       foreach($group in $groups) {               {
           $strGroup = $group.split(',')[0]
           $strGroup = $strGroup.split('=')[1] 
           "     "+$strGroup
           if ($strGroup -match "WSUS") {
               $Target+", "+$strGroup | out-file -encoding ASCII  wsus-server-groups.csv -append
               }#if
           }#foreach
    }#if
}#foreach
###########################################################################

Powershell: List AD Group Membership


###########################################################################
#
#    List AD Group Membership of a user in specified OU
#
###########################################################################
$root=([adsi]"").distinguishedName
$ou=[adsi]("LDAP://ou=Engineering,ou=Chicago,ou=Information Technology,"+$root)
$user=$ou.psbase.children.find("cn=Smith\, Billy")
$groups = $user.memberof
foreach($group in $groups){
    $strGroup = $group.split(',')[0]
    $strGroup = $strGroup.split('=')[1]
    $strGroup
    }#foreach
###########################################################################

Group Policy Notes

"Stream of conciousness" notes on Group Policies

FWIW

- either the computer settings or the user settings get applied, not both -- as one might expect.
- e.g. logging on machine in TRAINING OU - only the computer settings are applied (since user object is in another OU.)
- when appropriate - disable user or computer portion -- whichever doesn't apply.
- GP can link to domain, site, OU, local
- cannot be applied to container (e.g. builtin, computers, users)
- avoid using site GPO's.
- order of application: Local, Site, Domain, OU
- GPO components: GP Container, GP Template
- Advertise application = allows install from add/remote programs. (Publish = do the install automatically.)
-start-run dssite.msc, domain.msc, dnsmgmt.msc, winsmgmt.msc
- sysvol\[domain]\Policies (templates) - (must match) AD System\Policies container
- GUID's are universal.
- Other paths to GPT - group policy templates - both of the below point to the exact same location

c:\windows\sysvol\domain\policies

c:\windows\sysvol\sysvol\[domain]\policies
- When working directly with GPT's always use: c:\windows\sysvol\domain\policies
- GPC replicates with AD. GPT's replicate via RPC with FRS or DFSR (in 2008AD functional level)
- In 2003, ADSIEDIT shows properties and replication status of policies.
- ADM folder on sysvol is not necessary, access to them from somewhere is needed when administering.
- a copy of this folder is made for every policy - this is the vast majority of the space consumed for policies on sysvol
- versions - bit 5 from right is incremented when user policy is changed, bit 1 is incremented when computer policy is changed.
- do NOT disable default domain policy and make your own domain policy.

- If you copy the default domain policy and disable the default domain policy and work from the copy "works" but some software looks for the GUID for adjusting.
- just leave the default domain policy blank and create another policy.
- SYSVOL replication can use DFSR in 2008 functional level domain. Requires running DFSRMIG.EXE

- Local policies are saved in: c:\windows\system32\GroupPolicy
- gPLink points to the GPC, GPC points to GPT
- GPC stores version number in "VersionNumber" attribute of the GPO.
- GPT stores version number in GPT.INI file
- utility named GPOTOOL can help identify issues or problems.
- refresh interval
- DC's - 5 minutes
- Others - 90-120 minutes
- run GPRESULT /V - shows what happened last time policy was applied - uses RSOP which requires read permission for domain.

- ADPREP /DOMAINPREP /GPPREP -> sets permissions.
- Restore Domain Policies to default and resets ACLs - caution! Find KB article for caveats.
- DCGPOFIX.EXE - Win2003 & later
- RECREATEDEFPOL.EXE - Win2000
- Templates

- ADM - pre-Vista - language specific - required for each policy
- ADMX - based on XML - Vista & later
- ADML files - associated with an ADMX file - language specific portion of template.
- c:\windows\PolicyDefinitions on Vista and later machines.

- GPMC - Group Policy Management Console
- v1 - Windows XP, 2003
- v2 - Vista and later
- administer from one or the other not both.
- Go into GPMC and backup GPO's!!!!!!!!!!!!!!!!!!!!!!!!!!!
- custom ADM files must be imported.

- Using a Central Store of ADMX files: KB929841

PING test

PowerShell to PING a list of computers.

##########################################################################
# 
#    PING List of Machines
#
##########################################################################

$computers = get-content list.txt
$ping = new-object system.net.networkinformation.ping
$pingreturns = @()
foreach ($entry in $computers) {
  $entry = $entry -replace "\s{2,}", ""
  if ($entry.length -eq 0) {$entry = 'NOTHING'}
  $result = $entry+" "+(Test-Connection -ComputerName $entry -quiet -count 1)
  $result
  $result | out-file -encoding ASCII -filepath RESULT.TXT -append
  }#foreach

E-mail to Cell Phone

Here's a reference of how to e-mail someone's cell phone if you know who their cell provider is:
Verizon ........ 10digitphonenumber@vtext.com
     AT&T ........... 10digitphonenumber@txt.att.net
     Sprint ......... 10digitphonenumber@messaging.sprintpcs.com
     T-Mobile ....... 10digitphonenumber@tmomail.net
     Nextel ......... 10digitphonenumber@messaging.nextel.com
     Cingular ....... 10digitphonenumber@cingularme.com
     Virgin Mobile .. 10digitphonenumber@vmobl.com
     Alltel ......... 10digitphonenumber@message.alltel.com
     CellularOne .... 10digitphonenumber@mobile.celloneusa.com
     Omnipoint ...... 10digitphonenumber@omnipointpcs.com
     Qwest .......... 10digitphonenumber@qwestmp.com
     Metro PCS ...... 10digitphonenumber@mymetropcs.com

E-Mail to Cell Phones

If you know somebody's cell phone provider you can send them a text via e-mail.
Verizon:       10digitphonenumber@vtext.com
AT&T:          10digitphonenumber@txt.att.net
Sprint:        10digitphonenumber@messaging.sprintpcs.com
T-Mobile:      10digitphonenumber@tmomail.net
Nextel:        10digitphonenumber@messaging.nextel.com
Cingular:      10digitphonenumber@cingularme.com
Virgin Mobile: 10digitphonenumber@vmobl.com
Alltel:        10digitphonenumber@message.alltel.com
CellularOne....10digitphonenumber@mobile.celloneusa.com
Omnipoint......10digitphonenumber@omnipointpcs.com
Qwest..........10digitphonenumber@qwestmp.com
Metro PCS......10digitphonenumber@mymetropcs.com 

Powershell: List AD Machine Accounts


######################################################################
#
# List all Windows Servers with machine accounts in Active Directory
#
######################################################################

$ServerList = 'c:\allservers.txt'
New-Item $serverlist -Type file -Force >$nul

$strCategory = "computer" 
$strOS = "Windows*Server*"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry 
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher 
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("OperatingSystem=$strOS")
$colProplist = "dnshostname"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()

foreach ($objResult in $colResults)  { 
  $objComputer = $objResult.Properties;  
  $Server = $objComputer.dnshostname
  $Server = $Server -replace "\s{2,}", ""
  $Server = $Server -replace "\.US\.DOMAIN\.COM", ""
  write-output $Server | out-file -encoding ASCII -filepath $ServerList -append
  }#foreach

Powershell: List the members of a group


$root=([ADSI]"").distinguishedName
$Group = [ADSI]("LDAP://CN=Domain Admins,CN=Users,"+$root)
$Group.member

Powershell Text Output Mystery

One night I spent a good while puzzling over why my text output from a powershell script wasn't working when I opened it in excel as CSV.
It looks beautiful in TextPad and Notepad. I went down the garden path for a little while when I noticed that when I edited some aspects of my record format and saved the file from the editor it opened perfectly in Excel. So I made changes to my script to reformat the output but it had the same problem. And then I noticed that it didn't matter if I changed anything in the editor, all I had to do was save it from the editor and my problem was magically solved.
This led me to open it in HEX edit mode and found some ponderous bytes at the beginning of my file: "FF EE". A little googling led me to the answer.
By default powershell adds a “byte order mark” to the beginning of it's output. See WikiPedia
Use: out-file -encoding ASCII to prevent this from happening.

Speed Up Internet Explorer

Do more than 2 things at once in Internet Explorer:
http://support.microsoft.com/kb/282402
To increase the number of files that you can download at one time to 10, follow these steps:
  1. Start Registry Editor.
  2. Locate the following key in the registry: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
  3. On the Edit menu, point to New, click DWORD Value, and then add the following registry values:
    Value name: MaxConnectionsPer1_0Server
    Value data: 10
    Base: Decimal
    Value Name: MaxConnectionsPerServer
    Value data: 10
    Base: Decimal
  4. Exit Registry Editor.
For Internet Explorer 8.0
How to configure the connection limit by modifying a registry key
Start Registry Editor.

  1. Locate the following key in the registry:
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER
  2. On the Edit menu, point to New, click DWORD Value, and then add the following registry values:  
  3. Value name: iexplore.exe
    Value data: 10
    Base: Decimal
 
Note set this value to the connection limit that you want for HTTP 1.1 connections. By setting the value to 10, you increase the connection limit to 10.
 
  1. Locate and then click the following registry subkey:
    HEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER
  2. On the Edit menu, point to New, click DWORD Value, and then add the following registry values:
    Value name: iexplore.exe
    Value data: 10
    Base: Decimal
Note set this value to the connection limit that you want for HTTP 1.1 connections. By setting the value to 10, you increase the connection limit to 10.
Exit Registry Editor.

Which switch is which?

I couldn't remember which devices were the oldest ones in a branch office where we planned to replace some gear.
You would think that somewhere in SHOW VER there would be a manufacture date of a switch or router.
After a long time staring at various output from SHOW commands a friend of mine "googled it for me" (see LetMeGoogleThatForYou)
and came up with this helpful information:
> Anyone know how to locate the manufacturing date a switch?
Do a "show version" and locate the System Serial Number.
The serial number is in this format: LLLYYWWSSSS
LLL = location of the supplier
YY = year of manufacture
WW = week of manufacture
SSSS = serial-id
Year codes:
01 = 1997
02 = 1998
03 = 1999
04 = 2000
05 = 2001
06 = 2002
07 = 2003
08 = 2004
09 = 2005
10 = 2006
11 = 2007
12 = 2008

Antivirus Exclusions

So may times a long bout of troubleshooting with a pesky problem ends up being something obvious. It is not always obvious when virus protection is causing a problem. When I reach that first point of scratching my head saying "this doesn't make sense" I try to make a point of eliminating antivirus from the mix and testing again.
Often the software vendor will have recommendations on which of their working directories or configuration files need excluded.
Check out this great resource for Microsoft Antivirus Exclusions

iSCSI and VMWare

Some iSCSI may be in my future. Unless we jump straight to NFS.
This is a great article: VirtualGeek

Cisco IOS

We used to have to pay more for the IP Advanced version of IOS to run OSPF on our branch office core routers.
Now I am told that we can run at least one instance of OSPF in IP Base license (cheaper) when running IOS ver 12.2.55se1

AD Attributes Reference

ADSI & LDAP in scripts is very powerful, but there are so many little details to get right. There are often ways to make a script to see all your options, but sometimes it's good to be able to just look up what exactly attribute names are or see a list of them all.
Here on MSDN

Check internet routes to my network

helpful for testing:
telnet route-views.routeviews.org

3/26/2011

Powershell: Add members to AD group


$users = get-content add.txt
$target = "testGroup"
"=============================="
" ADD TO " + $target
"------------------------------"
 $ds = new-object directoryServices.directorySearcher 
 $ds.filter = "(&(objectClass=Group)(name=$target))" 
 $dn = $ds.findOne() 

 if ($dn) { #found
    $group = [ADSI]$dn.path 
    $groupDE = [ADSI]"LDAP://$($group.distinguishedname)" 

    foreach ($name in $users)
     {
     $ds.filter = "(&(objectCategory=computer)(objectClass=user)(name=$name))" 
     $dn = $ds.findOne()
     if ($dn) {
     $usr = [ADSI]$dn.path
     $ADuser = [ADSI]"LDAP://$($usr.distinguishedname)"
     "    "+$ADuser.name
      $groupDE.add("LDAP://$($ADuser.distinguishedName)")  
              }#if
        }#foreach
    }#if
"------------------------------"

3/25/2011

Powershell: Find inactive group members

Get the members each group in the list. if the members are on a list of inactive accounts, flag them in the output.

$root=([ADSI]"").distinguishedName
 
$Groups=get-content groups.txt
$Accounts=get-content inactive.txt
 
foreach ($Group in $Groups) {
    "-----------------------------------"
    $Group+":"
    $Group = [ADSI]("LDAP://CN=$Group,CN=Users,"+$root)
    $Output = $Group.member –Replace ‘\,.*$’, ‘’
    $Check = $Output -Replace 'CN=',''
    foreach ($Item in $Check) {
        $test = $Item.ToLower()
        if ($Accounts -contains $test) {
            "***************"+$test
            }
            else {
            $test
        }
    }
}

3/20/2011

Code in text box with scroll bars

The following is the CSS used in my template to quote code with <PRE> <CODE>:

pre { 
 font: 100% courier,monospace; 
 width: 100%;
 overflow-x: auto;
 max-height: 400px
 border: 1px dotted #281;
 border-left: none;
 background-color: #fff;
 padding-bottom: 16px;
 font-size: 1em;
 word-wrap: normal;
}

code { 
 font: 100% courier,monospace; 
}

3/19/2011

Powershell: RegEx

Lately I've been doing RegEx replacement with powershell instead of Perl because it has turned out to be so intuitive.
I've also had a bit of fun doing various powershell one-liners from the command line for stuff I just need to do quickly and probably don't need again. For example:

Powershell -command $allservers = get-content allservers.txt; $allservers -Replace ‘\.corp\.domain\.com’, ‘’
the above executes powershell and runs a command that reads in a file of servers' dns names and then writes to the screen the list without the domain part of their name.
Also, I often use TextPad (www.textpad.org) to use a more complicated RegEx against a file.

Powershell: Strings

text search and replace in a string is so easy:
$a = $a.Replace("Scriptign", "Scripting")
Lots of stringy stuff in a great technet article

Hash of Arrays

Advanced data structures are sometimes so complicated that I have no use for them. However I have found that a hash of arrays is very useful. Gathering data into the structure and retrieving it is elegant and saves a lot of strange contortions using variables just for looping and incrementing an index/etc. (For example, for each mailbox in a list write $alias[$mailbox]. Or just $alias['JimBob']...)
However, moving from Perl to Powershell I found myself having to re-learn how to make them work.
The following junk helped me to experimentally muddle through the process in PowerShell:
$List = 'User1','User2'
$MBX = 'Box1','Box2'
$MBX += 'Box2'
#$prm=@{$MBX=$List}
$prm=@{$MBX[1]='User1','User2'}
$prm.($MBX[1])+='User3'
$prm
write " "
$MBX = $MBX | Select -Unique
$MBX

TLS Testing

A while back I found myself needing to verify that my e-mail gateways support for TLS was still working after some system changes. Rather than having to find a live person to test with, a search turned up this testing site. It is very convenient and a cool way to test.
www.checktls.com

Interesting Article

I've had a lot of questions and speculation coming my way about hosted Exchange and "cloud" this and that.
(The Cloud reminds me of how nobody really knew what an extranet was back in the 90's but talked about it all the time...)
This is a very good article about pros and cons of hosted Exchange.