ESXi 4.0.0 to 5.0.0 Upgrade in my Lab

October 28th, 2011 by Steve No comments »

I just upgraded my ESXi host from 4.0.0 208167 to 5.0.0 469512.  Why was I still at 4.0.0?  Just laziness I guess…and the fact that it was working just fine for my lab purposes.  The upgrade process was mostly smooth:

  • I downloaded the ESXi 5 installable ISO from VMware
  • Booted my system with it and let it perform the upgrade.

I did experience the warnings described here because my ESX 4 build came from Dell directly, but apparently none of the custom Dell VIBs were needed…ESXi 5 is running fine and all my existing VMs work perfectly.  Now to upgrade the VMTools on all my VMs…

Determine How Many ESX Hosts are Needed

February 7th, 2011 by Steve 2 comments »

If you have ever looked for a calculator to tell you how many ESX host are needed based on the VMs you need to run then look no further.  I put together a spreadsheet for myself when I needed to do this and I thought it might help others.  It is very easy to use.  Start on the “VMs Req.” tab and enter the information about the VMs you need, including vCPUs and RAM.  Then, on the “Hosts Req.” tab, edit the information in the “Host Profile” section so that it reflects your host’s information.  If desired, change the information in “Misc.” section.  Once you are done entering information the results are in yellow at the bottom.  If you have any feedback on how to make this better please let me know.  By the way, the password on the spreadsheet is “password”, in case you want to make edits.

Download the Spreadsheet

DPM 2010 SQL Agent Shows No Databases Available for Backup

August 24th, 2010 by Steve No comments »

I ran into an issue in my lab and after some valuable assistance on the Microsoft System Center DPM forums I was able to resolve it.

Issue: After installing DPM 2010 agent on my multi-instance (2 named, 1 default) SQL 2008 SP1 server, when I create a protection group, and expand this server, I see no databases to backup.  I only see the “All Shares”, “All Volumes”, and “System Protection” options under the server.  A helpful person on the MS forum asked me if the SQL Server VSS Writer service was set start automatically and whether it was running.  Bingo! In my case some install on my SQL server had made it so the SQL VSS Writer service could not start.  I was getting the following events in my application event log when trying to start the service:

————————————

Log Name:      Application
Source:        SideBySide
Date:          8/24/2010 9:59:03 PM
Event ID:      33
Task Category: None
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      rfsql1.rf.pvt
Description:
Activation context generation failed for
"C:\Program Files\Microsoft SQL Server\90\Shared\sqlwriter.exe".
Dependent Assembly Microsoft.VC80.ATL,processorArchitecture="amd64",
publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="8.0.50727.4053"
could not be found. Please use sxstrace.exe for detailed diagnosis.

———————————

Resolution: I did a repair installation of all SQL instances.  After this I could start the SQL VSS Writer service and my databases showed up in DPM so I could back them up.

Home Lab…Complete!

July 30th, 2010 by Steve 3 comments »

Home Lab - Logical View

I am very excited as I finally got my home lab complete!  Check it out and tell me what you think.

Perimeter switch, internal switch, and WAP

8 TB NAS (iSCSI Support), cable modem, and UPS

ESXi 4.x Host (1x Quad-Core, 16 GB RAM)

Windows 2008 R2 – File Management Tasks

March 10th, 2010 by Steve 3 comments »

There is a really neat post on Adi Oltean’s Blog concerning the use of Windows 2008 R2′s File Management Tasks (FMTs) to archive data.  He uses a “Custom” task type and refers to a batch script which moves files and leaves a symbolic link.  This is sort of a “poor man’s” HSM solution, admittedly, but still pretty cool and instructive as to what can be accomplished with FMTs (anything you can script!).  His script is below:

if exist "c:\protected\%~pnx1" @echo Target file already exists! & goto :EOF 
md "c:\HSM\%~p1" 
move %1 "c:\protected\%~p1" 
mklink %1 "c:\protected\%~pnx1"

If you are wondering (like I was) what the heck “%~p1″ or “%~pnx1″ means, check out this site.

I set up a similar FMT in my test environment to learn about this technology, but I had problems with Adi’s batch script.  It was hard to debug because it has no logging, so I wrote my own in VBS with lots of logging.  You can download my script here.  Here is how I set up my FMT.

1.  On the General tab enter a task name and the Scope.  The scope is where the FMT run against.

2.   On the Action tab choose “Custom” for the Type.  For the Executable section enter the path to cscript.exe.  In the Arguments section enter the path to the script (download above), and choose the [Source File Path] variable to insert.  Command Security should be set to Local System.

3.  On the Condition tab place a check mark inside the Days since file was last accessed box.  Note the property conditions section of this tab.  Here you can add file classifications you have previously set up.  For a great read on Microsoft’s File Classification Infrastructure read the Storage Team’s blog about itNote, if you want to use “Last Accessed” time for your FMT as I did you need to enable the tracking of this attribute.  This is done by setting HKLM\System\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate to 0 (this value is REG_DWORD).  Note that this could impact disk IO performance on busy file servers!

4.  On the Schedule tab enter whatever schedule/frequency is desired.

Finally, use a Windows “Touch” utility (download one here) to alter the Last Accessed date of a file that falls within the scope of the FMT you created.  Then manually run your FMT (Right-click > Run Now) and if all is well the file you altered should be moved and a symbolic link left in it’s place.

System Center Operations Manager 2007 R2 – How to Install a Gateway Server

March 10th, 2010 by Steve 2 comments »

Installing a Gateway server in your existing OpsMgr environment is a fairly challenging task.  When accomplishing this task for a customer I found many resources which helped, but I could not find one that was complete.  The process I found which was the most helpful was Brad Hearn’s blog.  Much of my documented process comes from his document.  Honestly I would never have gotten my gateways operational without Brad’s excellent post so many thanks!

Download “How to Install a Gateway Server.pdf” here.

OpsMgr 2007 DMZ-Based Agents Fail to Report to Gateway with Event ID 20070

February 19th, 2010 by Steve 4 comments »

We recently noticed most of our DMZ-based OpsMgr agents were not connecting to their gateway server.  On the agent we saw the following event:

Event Type:          Error
Event Source:       OpsMgr Connector
Event Category:    None
Event ID:              20070
Computer:            <Computer>
Description:          The OpsMgr Connector connected to <domain>, but the connection was closed immediately after authentication occurred.  The most likely cause of this error is that the agent is not authorized to communicate with the server, or the server has not received configuration.  Check the event log on the server for the presence of 20000 events, indicating that agents which are not approved are attempting to connect.

On the gateway server the following event was being logged:

Event Type: Information
Event Source:        OpsMgr Connector
Task Category: None
Event ID:      20000
Description: A device which is not part of this management group has attempted to access this Health Service.  Requesting Device Name : <computer>
The strange thing is that these agents had been working fine, and a few still were working!  We checked the usual things and did the usual recovery steps:
  • Is TCP 5723 open to the gateway server?
  • Restart the HealthService
  • Is agent in Pending Management?
  • Restart the HealthService
  • Wait 5 minutes
  • Restart the HealthService

All to no avail.  We found http://blogs.technet.com/operationsmgr/archive/2009/02/17/opsmgr-2007-port-requirements-for-scom-agents-in-a-dmz.aspx which suggested opening ports 88 and 389 from the agent to the RMS. This did not make sense to us since some agents were working.  So we used Netmon 3.3 to trace the client while the HealthService starts.  It never used any port but 5723.

We even enabled verbose diagnostic tracing (http://support.microsoft.com/kb/942864) and reviewed the logs.  We saw where the 20070 event was being generated but not much interesting besides that:

5412.5956::02/19/2010-10:46:56.978 [Common] [] [Verbose] :Common::EventLogUtil::LogEvent{EventLogUtil_cpp311}Logging error event 20070 with args “<servername>”, “NULL”,”NULL”, “NULL”, “NULL”, “NULL”, “NULL”, “NULL”, “NULL”

5412.5956::02/19/2010-10:46:56.978 [Common] [] [Information] :Common::EventLogUtil::LogEvent{EventLogUtil_cpp397}Logging event 20070 from source “OpsMgr Connector” with severity Error and description “The OpsMgr Connector connected to <GatewayServer>, but the connection was closed immediately after authentication occurred.  The most likely cause of this error is that the agent is not authorized to communicate with the server, or the server has not received configuration.  Check the event log on the server for the presence of 20000 events, indicating that agents which are not approved are attempting to connect.”.

Solution…

We finally had to call Microsoft.  After about 30 minutes of troubleshooting the engineer saw that the OpsMgrConnector.Config.xml file in the C:\Program Files\System Center Operations Manager 2007\Health Service State\Connector Configuration Cache\<MgmtGrpName> folder on the gateway server was last modified several weeks ago.  He had us rename the Health Service State folder under C:\Program Files\System Center Operations Manager 2007 and restart the HealthService.  After this a new Health Service State folder was created and the OpsMgrConnector.Config.xml had a much more current last modified date.  We then restarted the HealthService on the agents and they reported in to the gateway server correctly.

Extend System Center Configuration Manager 2007 to Collect Fibre Channel HBA Information – Revised

January 6th, 2010 by Steve 18 comments »

Version 2…

In my original post on this subject I described how to set up ConfigMgr to grab data from the MSFC_FCAdapterHBAAttributes class under Root\wmi.   Later I found out that, as least in my environment, the data in this class was unreliable.  It would literally be there one day and the next it would have disappeared.  So I had to change my approach.  This new method of getting HBA info into ConfigMgr is not exactly elegant, but it is effective.  Use it at your own risk! The process is as follows:

  1. Install Microsoft’s FCInfo utility on your machines with HBAs.  I packaged this up and deployed to a collection populated with these machines.  Note that the install will throw an error on Windows Server 2008 but the utility still works and it MUST be present for this process to work!
  2. Update sms_def.mof to look for HBA info in a new class called Custom_HBA_Info (later steps actually create this class).  Add the below text to your sms_def.mof (always make a backup first!).

#pragma namespace ("\\\\.\\root\\CIMv2\\sms")
[SMS_Report(TRUE),
SMS_Group_Name("Custom_HBA_Info"),
SMS_Class_ID("Microsoft|Custom_Frost_HBA_Info|1.0"),
Namespace("\\\\\\\\.\\\\root\\\\CIMv2")]
class Custom_HBA_Info : SMS_Class_Template
{
[SMS_Report(TRUE), key ]
string	Adapter;
[SMS_Report(TRUE)]
string	NodeWWN;
[SMS_Report(TRUE)]
string	PortWWN;
[SMS_Report(TRUE)]
string	SerialNumber;
[SMS_Report(TRUE)]
string	DriverName;
[SMS_Report(TRUE)]
string	DriverVersion;
[SMS_Report(TRUE)]
string	FirmwareVersion;
[SMS_Report(TRUE)]
datetime DateCollected;
};

Almost immediately after saving the sms_def.mof file ConfigMgr will compile it.  You can monitor the success/failure of this in the dataldr.log file on the ConfigMgr server (<install_dir>\Logs).

3.  Download my script (rename to GetHBAInfo.vbs)  to a share on your network.  The script creates the WMI class referenced above, runs fcinfo.exe, grabs the output, and populates it into Custom_HBA_Info.

4.  Create a Software Distribution package for the script.  Create a Program for the package with the following command line: %systemroot%\system32\cscript.exe GetHBAInfo.vbs

5.  Schedule a recurring advertisement associated with a collection containing all your machines with HBAs.  My advertisement runs once per week.

Thats it.  Now, to be sure it is working:

1.  Run your advertisement so that the script runs on your agents with HBAs.

2.  On one of those computers use wmic to validate the presence of the namespace.  Command syntax:

wmic path Custom_HBA_Info

If an Invalid Class error is displayed then either the script has not run or it has an error.  The script logs it’s results under %windir%\Temp in a file that starts with GetHBAInfo_<date>_<time>.log.

3.  Force a couple of agents to run their hardware inventory.  Monitor the dataldr.log on the site server.  You should see lots of data flying by as the agent updates it hardware info.  When complete search for the string “Custom_HBA_Info”.  If you find it then the data should have gotten put in your site database.  Look for a table in the database called dbo.Custom_HBA_Info_Data.  If it exists then you should be golden.

4.  Use Resource Explorer to view one of your machines with HBAs.  Under Hardware you should see Custom_HBA_Info, and your data should be there.

Special thanks to my co-worker Jason Sandys, a ConfigMgr MVP.  Without his assistance I would not have gotten this to work.

Return HBA World Wide Name from WMI

December 16th, 2009 by Steve 1 comment »

I searched quite a bit looking for a way to get an FC card’s WWN from WMI.  I found some information indicating it might be in the root\WMI namespace so I used Scriptomatic 2.0 to look through the classes in that namespace until I finally found it.  It was in QL_FibrePortNPIVAttributes (I assume this classis added by the QLogic driver installation…yeah the QL gave it away…).

Unfortunately the numbers of the WWN are returned in decimal rather than in hex, the digit groups are returned separated by commas, and single digits are used when the number is below 10.  So it looks like this:

WWPN: 80,6,11,0,0,194,154,2

Well, we can’t have that!  So I wrote a script to grab the information and convert it hex, group digits with a colon and “pad” an extra zero if the decimal value was under 10.  Here is the script:

On Error Resume Next

Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

arrComputers = Array(".")
For Each strComputer In arrComputers
	Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\WMI")
	Set colItems = objWMIService.ExecQuery("SELECT * FROM QL_FibrePortNPIVAttributes", "WQL", _
                                          wbemFlagReturnImmediately + wbemFlagForwardOnly)
	For Each objItem In colItems
		var1 = objItem.WWPN
		For i = 0 To UBound(var1)
			If len(Hex(var1(i))) < 2 then
				var2 = "0" + Hex(var1(i))
			Else
				var2 = Hex(var1(i))
			End If
			tmpVar1 = tmpVar1 & ":" & var2
			tmpVar2 = mid(tmpVar1, 2)
		Next
		wscript.echo tmpVar2
		tmpVar1 = ""
		tmpVar2 = ""
	Next
Next

This returns a beautifully formatted (yes I am a geek) WWN…observe:

50:06:0B:00:00:C2:9A:00

Printer Migration Client Script

November 3rd, 2009 by Steve 3 comments »

If you have ever had to migrate all the printers from one Windows print server to another, the server side part is pretty easy.  Windows 2008 includes the Printer Migration Wizard which can migrate the queues.  Prior to Windows 2008 there was an outstanding utility called Print Migrator (PrintMig) which made it a snap.

However the client side is a bit more tricky.  Since there is a different server name in the printer share path the clients will be broken after the migration.

Printer share  path on old server: \\OldPrnSrv\Printer1

Printer share path on new server: \\NewPrnSrv\Printer1

This problem can be further complicated if during the migration you took the opportunity to standardize Printer/Printer Share names.  I had this exact problem at a client.  I solved it with a GPO-based logon script and input file.  Before I go into how to implement this, first a little about the script.

  • The script first checks for the existence of a “check” file.  If the check file exists then we assume the script already ran and we exit.
  • Then the script records the user’s default printer as it will need this info later to ensure the same device is set as default after the printer reconnect.
  • Next the script walks through the input file and attempts to disconnect each “old” printer connection and reconnect to the new.  If the printer share in the input file is not defined on the person’s machine then it skips that line and moves on to the next line/printer.
  • Once all the input file has been traversed the script resets the person’s default printer and creates the “check” file.

Here is the script code.

On Error Resume Next
Const ForReading = 1

Set WshNetwork = CreateObject("WScript.Network")
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists("c:\PrinterReconnectFinished.txt") then
Set f1 = fso.OpenTextFile(GetPath() & "input.txt", ForReading)

varDefault = GetDefaultPrinter()

tmpArr = Split(f1.readall, vbcrlf)
for i = 0 to UBOUND(tmpArr)
    If instr(1, tmpArr(i), varDefault, 1) then x = i
    err.clear
    tmpVar = split(tmpArr(i), "~")
    WshNetwork.RemovePrinterConnection tmpVar(0)
    If err.number = 0 then WshNetwork.AddWindowsPrinterConnection tmpVar(1)
next

var1 = split(tmpArr(x), "~")
ConfigDefaultPrinter(var1(1))
    Set f2 = fso.CreateTextFile("c:\PrinterReconnectFinished.txt", True)
    Set f3 = fso.Getfile("c:\PrinterReconnectFinished.txt")
    f3.attributes = f3.attributes + 2
End If

'*************************************************************************************************
Sub ConfigDefaultPrinter(name)
        '*****************************************************************************************
        '*****************************************************************************************
        ' Purpose:  This sub routine defines a default printer based on the printer name passed to
        ' it.
        ' Version 1.0
        ' Arguements:  None
        '*****************************************************************************************
        '*****************************************************************************************
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & _
    strComputer & "\root\cimv2")
    Set colInstalledPrinters =  objWMIService.ExecQuery _
    ("Select * from Win32_Printer Where Name = 'name'")
    For Each objPrinter in colInstalledPrinters
            objPrinter.SetDefaultPrinter()
    Next
End Sub
'*************************************************************************************************

'*************************************************************************************************
Function GetDefaultPrinter()
        '*****************************************************************************************
        '*****************************************************************************************
        ' Purpose:  This Function returns the default printer as configured on the client.
        ' Version 1.0
        ' Arguements:  None
        ' Returns:  Text string
        '*****************************************************************************************
        '*****************************************************************************************
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & _
    strComputer & "\root\cimv2")
    Set colInstalledPrinters =  objWMIService.ExecQuery("Select * from Win32_Printer")
    For Each objPrinter in colInstalledPrinters
        If objPrinter.Default then
            GetDefaultPrinter = objPrinter.Name
        End If
    Next
End Function
'*************************************************************************************************

'*************************************************************************************************
Function GetPath()
    '*********************************************************************************************
    '*********************************************************************************************
    ' Purpose:  This Function returns the path where the script is currently being executed.
    ' Version 1.0
    ' Arguements:  None
    ' Returns:  Text string
    '*********************************************************************************************
    '*********************************************************************************************
    Dim path
    path = WScript.ScriptFullName
    GetPath = Left(path, InStrRev(path, "\"))
End Function
'*************************************************************************************************

Here’s how you can implement this solution.

1. Create an input file and put each old printer share path and new share path on a new line separated by a “~”.  It should look like this:

\\OldPrnSrv1\Printer1~\\NewPrnSrv1\Printer1
\\OldPrnSrv1\Printer2~\\NewPrnSrv1\Printer1
etc...

2. When you have all the printer share paths entered in your input file save it as input.txt.

3. Next download the printer migration script here.  Strip the “.txt” off of the end of the name.

4. Save the input.txt and script files in the domain scripts share (\\mydomain.com\SYSVOL\mydomain.com\scripts).

5. Create a new Group Policy Object (GPO) called Printer Reconnect. NOTEDon’t link it to any container yet.

6. Edit the GPO under User Configuration>Windows Settings>Scripts double-click Logon.

7. Click the Add button, then Browse.  Locate/select the PrinterReconnect.vbs script in the path you saved it to previously.

8. Click OK and make sure the script is displayed on the Logon Properties screen.  Click OK.

Once all printers are migrated to the new server and well tested, you should be ready to have the clients reconnect to the migrated queues on the new server.  ONLY when ready to have clients reconnect, go to the next step.

9. Link the Printer Reconnect GPO to an appropriate container to apply the logon script to targeted users.

As always, use this at your own risk.  Let me know if you have any issues and I will help out as I can.