How-To: Microsoft Online Services (Currently BPOS) Cmdlet Reference for the Migration Command Shell

Here’s a full list of BPOS-specific PowerShell commands that can be run through the Migration Command Shell after installing the 32-bit or 64-bit version of the migration utility (32-bit: http://www.microsoft.com/downloads/details.aspx?familyid=9ed5f4c1-7f0b-4506-a214-32093af6147a&displaylang=en, 64-bit: http://www.microsoft.com/downloads/details.aspx?familyid=5547634c-5e49-4dbd-b6b0-457b38a75f33&displaylang=en):

http://technet.microsoft.com/en-us/library/cc742577.aspx

Each link will take you to the command page with usage guidelines (current as of today, 3/25/2011):

And, of course, the undocumented command, for when you want to forward e-mail to a BPOS user to another e-mail address without involving Microsoft PSS:


Set-MSOnlineAlternateRecipient -Identity "internalemailaddress@domain.com -AlternateRecipient "externalemailaddress@domain.com -DeliverToBoth $False


1)  If you want e-mail to go to the mailbox and the forwarded address, you can change $False to $True

2)  The external email address must first be created as a contact from https://admin.microsoftonline.com before running the above command 

How To: Determine When a User Was Deleted from Active Directory

This will come in handy… especially if you’re not auditing your security events fully.  By default, account deletions & changes are not part of the Security log in the Event Viewer.  So… you’re kind of out of luck in terms of finding a “GOTCHA!” type event log that displays when the account was deleted & by whom if you haven’t tweaked the default Auditing settings.  As always, there are ways around this… :-)

1) Hop on a Domain Controller

2) Download adrestore.exe from http://live.sysinternals.com and save it to the root of the C:\ drive (you should also check out Mark Russinovich’s other tools if you have time later: http://technet.microsoft.com/en-us/sysinternals/bb545027)

3) Open up a command prompt and get back to the root of C:\ by typing cd \ and hitting Enter

4) Run the following command:

    adrestore > list.txt & notepad list.txt

   

5) Run through the Notepad document looking for cn: _______ where _______ is the user’s name, then copy the entire distinguishedName line in that same block starting with CN= to the clipboard:

   

6) Back at the command prompt, run the following command, making substitutions where noted with []:

    repadmin /showobjmeta [Current Server (DC) Name] “[Paste here]” > output.txt & notepad output.txt

7) Search through the Notepad document for “isdeleted” (using Ctrl-F) and the date/time on the same line is when it was deleted:

   

8) Now that you know when the account was deleted, you can try searching for Event ID 630 in the Security log… again though, you’re doing all of this because auditing of those types of events is not on by default… but hey, you might get lucky.  At any rate, you can use whatever other tools you have at your disposal to narrow down “Whodunit.”

Don’t forget to delete list.txt and output.txt from the root of the C:\ drive!

Fix: Citrix Access Essentials & SSL Certificate Renewals: Correcting Incorrectly-Initiated Certificate Renewals

If you’ve had the pleasure of renewing or creating SSL certificates for Citrix Access Essentials before, you know that there are two ways to renew a SSL certificate on a Citrix server:

Option 1: Renewing the certificate through Quick Start

Option 2: Renewing the certificate through IIS

If you renew the certificate in the way opposite the way the certificate was originally created, you will blow up the Citrix server.

If you run into a situation where the certificate was created in Quick Start but mistakenly renewed in IIS, then here’s what you’ll get:

…and here’s how to fix it:

1) Fire up Quick Start (Start > All Programs > Citrix > Quick Start)

2) Go to Setup > External Access and verify that “External access ______________ to the server is enabled.”

    If so, click on “Manage External Access.”

    If not, stop… this was probably set up through IIS instead of Quick Start.

   

3) Click Next on the 1st and 2nd screens (leaving the “External Access Method” the same as what has already been selected)

4) Highlight the old, expired certificate to re-activate the old SSL cert and click Next > Finish:

   

    (You will need to click yes on a “Are you insane? That certificate is already expired!” warning if it’s already expired.)

5) Now that the old cert is back in place, go into your IIS Manager (Server 2003: Start > All Programs > Administrative Tools > Internet Information Services (IIS) Manager)

6) Expand the [Server Name] > Web Sites and right-click on “Citrix Access Essentials External Site” and choose Properties

7) Go to the Web Site tab, remove any data from the “SSL port” field, and click OK:

   

8) Start up a Command Prompt, type iisreset and hit Enter

9) Check the Citrix site… it should be “back to normal,” but with an expired (or nearly-expired) certificate

10) Repeat steps 1-3 within Quick Start to get back to the screen where you select the certificate

11) Now, select the certificate that was mistakenly generated through IIS and hit Next > Finish:

   

12) Verify that the correct certificate is now installed by going to the Citrix site and viewing the certificate:

   

You’re done!  Now just make sure that the certificate always gets renewed through Quick Start in the first place (that’s step 13). :-)

How To: Properly Disable IPv6

If you’re ever experiencing oddities when trying to make service connections (SMB, AD replication, SQL, TS licensing, etc.) between servers or from servers to workstations and vice-versa and both ends of the equation are running either Vista, 7, or Server 2008, take a quick peek at the Local Area Connection settings.  If you see the “Internet Protocol Version 6” checkbox un-checked:

…then Sad Panda.

Un-checking IPv6 is very bad, mmmkay?  See here: http://msmvps.com/blogs/acefekay/archive/2010/05/27/how-to-disable-rss-tcp-chimney-feature-and-ipv6.aspx

The way to properly disable IPv6 is outlined here: http://support.microsoft.com/kb/929852

To save you all of that reading, here’s all you need to know:

To properly disable IPv6, run this Microsoft FixIt and reboot when prompted:

http://go.microsoft.com/?linkid=9732985

This too definitely falls into the, “You’d be shocked at how many issues this will solve” category.

Problem: Kaseya Scripting Ticket: "I Think You Meant \"

This is a ticket I’d just submitted to Kaseya regarding what I believed to be a deficiency in their recently-updated STEP commands (part of their Agent Procedures engine):

This will take some doing to follow along, so if you're in need of a cup of coffee, I'd advise getting it now :-)

###///COFFEE_BREAK///###

There, now that you have your coffee...

I very much appreciate the new commands... particularly "Execute Shell Command - Get Results to Variable" step type; however, I think it's broken.  Allow me to back up my assertion...

**********************
BIG HONKING DISCLAIMER
**********************

Yes, I know that Kaseya Support does not debug/diagnose/bless/curse/vex any sort of custom scripting... but I believe I'm going to point out a flaw in the "scripts-we-plebians-can't-see-that-make-up-the-STEP-commands-in-Agent-Procedures" scripts that ultimately needs fixed.  In other words, my script is fine... it's the inbuilt function calling my script that's broken.  Bear with me while I explain...


BACK STORY:

A client of ours has software called Faronics Deep Freeze installed on "lab" machines--essentialy disposable machines that were designed for guest use as an amenity at a chain of apartment complexes.  Deep Freeze (hereafter referred to as DF) is designed to "trick" Windows into thinking that configuration changes have been written to disk, even though they haven't been.  If a machine is "FROZEN," then any changes made to that machine's configuration while the machine was online are lost at the next reboot.  If a machine is "THAWED," however... then any changes you make become part of the machine's configuration until such time that the machine is "FROZEN" again.


THE PROBLEM:

Our Kaseya Agent versions are behind.  Our patching can't run on schedule (the machines revert back to and old configuration every night, and patching runs every week on Thursday mornings... so, for a fleeting moment all day Thursday, the machines are up to date... and after the Thursday night reboot, the machine reverts back to a 6-month-old configuration).  Anti-virus must update every day.  And finally, as a direct result of the agent version being out-of-date, LiveConnect crashes IE after the first minute of use.  Sad panda.

Sooooo... I was charged with figuring out how to fix this problem.

After much scripting and research, I came up with the script below:

As you can see, the script:

1) Stores the Agent Working Directory path as #AWD#
2) Writes a BOOTTHAWED.bat to #AWD#\BOOTTHAWED.bat
3) Impersonates the user "cwps" which is a preloaded Administrator account on all PCs
4) Runs the "Execute Shell Command - Get Results To Variable" step on #AWD#\BOOTTHAWED.bat
5) Deletes the #AWD#\BOOTTHAWED.bat file
6) Writes the #global:cmdresults# to the procedure log

Now, what is the BOOTTHAWED.bat file, you might ask... I'm glad you asked!

**FULL DISCLOSURE**: I know you guys are _not at all_ responsible for custom scripting.  And I don't expect you to debug this .bat file... or the script that calls it!  It all works just fine... it's the way that the .bat file is executed (via the "Execute Shell Command - Get Results to Variable" function) that's the problem.  Feel free to skip it if you don't speak BAT.

[BEGIN BAT FILE]

 @echo off

 if exist %WINDIR%\System32\DFC.exe goto 32bit
 if exist %WINDIR%\SysWOW64\DFC.exe goto 64bit

  echo "Deep Freeze does not exist on this machine"
 goto EOF

  :32bit
 %WINDIR%\System32\DFC.exe TheDeepFreezePassword /BOOTTHAWED
 goto CheckERRORLEVEL

  :64bit
 %WINDIR%\SysWOW64\DFC.exe TheDeepFreezePassword /BOOTTHAWED
 goto CheckERRORLEVEL

  :CheckERRORLEVEL
 if "%ERRORLEVEL%" == "0" goto 0
 if "%ERRORLEVEL%" == "1" goto 1
 if "%ERRORLEVEL%" == "2" goto 2
 if "%ERRORLEVEL%" == "3" goto 3
 if "%ERRORLEVEL%" == "4" goto 4
 if "%ERRORLEVEL%" == "5" goto 5

 echo "The ERRORLEVEL is not in the range of 0-5"
 goto EOF

  :0
 echo "SUCCESS or Boolean FALSE, for commands returning a boolean result"
 goto :EOF

  :1
 echo "Boolean TRUE"
 goto :EOF

  :2
 echo "ERROR - User does not have administrator rights"
 goto :EOF

  :3
 echo "Error - DFC command not valid on this installation"
 goto :EOF

  :4
 echo "ERROR - Invalid command"
 goto :EOF

  :5
 echo "ERROR - Internal error executing command"
 goto :EOF

  :EOF
 
[END BAT FILE]

So, to recap, I'm calling this fancy .BAT file which captures my %ERRORLEVEL% and echos the end result to the %STDOUT%.

That %STDOUT% should, in turn, be captured by the #global:cmdresults# variable... but it's not... and here's where it all breaks down.


THE SOLUTION:

I think you have a / in your "Execute Shell command - Get Results to Variable" built-in script where you should really have a \, which causes the step (and, ultimately, the whole script) to fail.  Here's the screenshot:

If I get what I think you're doing, the "Execute Shell command - Get Results to Variable" script does the following:

%ShellCommandToExecute% > %AgentWorkingDirectory%/commandresults.txt 2>%1

...when it really should be doing:

%ShellCommandToExecute% > %AgentWorkingDirectory%\commandresults.txt 2>%1

That, in turn, would reuturn whatever I'd echoed to %STDOUT% to the #global:cmdresults# variable and I'd know what was going on.

...but at present, I think that / is my stumbling block.

Am I right?  Did you mean to say \ instead of / in the "Execute Shell command - Get Results to Variable" script?

I hope they get back to me :-)