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

January 6th, 2010 by Steve 2 comments »

I spent awhile trying to get my ConfigMgr environment to collect HBA WWNs and with help from my co-worker Jason Sandys, a great doc he referred me to (Discovering Fibre Channel Topology through WMI) and various other sources I finally got it working.  Here’s the process.  As always, follow these steps at your own risk.

  1. Ensure the HBA information is populated in WMI.  If you are using Windows 2008 then the Microsoft Common HBA API and the MSFC_FCAdapterHBAAttributes WMI class is integrated in the OS out of the box.  If using anything before Win2008 then you need to install Microsoft’s FCInfo utility.  This utility installs the API and the WMI class under the root\wmi namespace.
  2. Validate that data exists by either running FCInfo or running this VBS script.  No HBA data from FCInfo or the script (or an error from the script) means you there is no HBA information on the system.  Ideally you will see something like this:FCInfo_Output
  3. On your ConfigMgr site server save a copy of the functional configuration.mof (<install_dir>\inboxes\clifiles.src\hinv).  Then edit the production copy by adding the following at the bottom and saving it:

//=============================
#pragma namespace ("\\\\.\\root\\wmi")
class MSFC_FCAdapterHBAAttributes
{
uint8 NodeWWN[];
string DriverName;
string DriverVersion;
string FirmwareVersion;
string HardwareVersion;
string Manufacturer;
string MfgDomain;
string Model;
unit32 NumberOfPorts;
string OptionROMVersion;
string SerialNumber;
};

4.   Save a copy of SMS_Def.mof (<install_dir>\inboxes\clifiles.src\hinv), then edit the functional copy by adding the following at the bottom and saving it:

#pragma namespace ("\\\\.\\root\\CIMv2\\sms")
[SMS_Report(TRUE),
SMS_Group_Name("MSFC_FCAdapterHBAAttributes"),
SMS_Class_ID("Microsoft|MSFC_FCAdapterHBAAttributes|1.0"),
Namespace("\\\\\\\\.\\\\root\\\\wmi")]
class MSFC_FCAdapterHBAAttributes : SMS_Class_Template
{
[SMS_Report(TRUE)]
uint8 NodeWWN[];
[SMS_Report(TRUE)]
string DriverName;
[SMS_Report(TRUE)]
string DriverVersion;
[SMS_Report(TRUE)]
string FirmwareVersion;
[SMS_Report(TRUE)]
string HardwareVersion;
[SMS_Report(TRUE)]
string Manufacturer;
[SMS_Report(TRUE)]
string MfgDomain;
[SMS_Report(TRUE)]
string Model;
[SMS_Report(TRUE)]
unit32 NumberOfPorts;
[SMS_Report(TRUE)]
string OptionROMVersion;
[SMS_Report(TRUE)]
string SerialNumber;
};

5.  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).

dataldr.log

If successful, data from your clients with HBAs will populate in the ConfigMgr database during their next scheduled hardware inventory.

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 No 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.

Desire = Entitlement?

September 4th, 2009 by Steve 7 comments »

As I was listening to NPR while driving home yesterday (A thing I recommend be done only sparingly and with great vigilance) I heard about the battle being waged in Maine over same-sex marriage.  You can read the story here.  As I listened I thought about the audacity of a group that would attempt to change the definition of an institution which has been established and unchanged for millennia.  I wondered at the mind set that thinks a “thing” can be redefined merely because of its observer’s wish.  It seemed to me (and still does) that such a person might equally state that a rock is now an eggplant and that it would be so just because they desire it to be.  It is not as though such people are insane, i.e. they do not look at a rock and see an eggplant.  It is that they believe the identity or meaning of a “thing” has no reference outside of their wish or desire.  It is not perception so much as it is will.  A thing may be a thing only if they allow it to be.  It has no “thing-ness” outside of their desire/will.

I also thought about the word “entitlement”.  I never cease to be amazed at the sense of entitlement people can have.  Those who would change the definition of marriage would do so because they feel entitled to “marry” their partner and gain all the benefits there of.  I tried to trace this thought pattern back to it’s source, and I came back to desire.  It is as though we believe that if we desire something strongly enough or have desired it for long enough that somehow we “deserve” it or we are “owed” it.  If we want it, it must be good and right.  We begin to feel antagonistic toward those who would presume to deny us this desire.  If someone disagrees they must be ignorant, bigoted, or worse.

So some questions I have include:

  • At what point did reality begin to depend on our will/desire? Reality is what it is.  Reason dictates that a thing is what it is whether I like/want/appreciate/agree with it or not.  Certainly a thing cannot be “A” and “non-A” at the same time and in the same relationship.  The essence of a thing is not affected one little bit by my perception of it, belief in it or desire concerning it.
  • When was it established that desire would equate with entitlement? My desire for something does not equate to my being owed that thing…no matter how long I have wanted it nor how strongly I want it.  When I think about it clearly, I am owed precious little in life.

Some may object that in the case of marriage, it is not an “absolute” reality but rather a “societal” reality, or that marriage has no meaning outside of what a society defines.  Such a belief is convenient for those in a society who would change the meaning of marriage.  If they can achieve change through whatever course allowed by their particular society then it will be altered in actuality.  However such a belief comes from somewhere.  All ideas do.  In this case, most likely the society gave themselves the right to define marriage.  They assumed ownership of the definition.  Such self-empowerment may be appropriate when setting arbitrary laws such as a speed limit but is marriage arbitrary?  Does the history of marriage extend from before such a society was in place?  Of course it does.  Marriage was created and given definition at creation…by the Creator.  When some religious leaders of His day asked Jesus about the permanence of marriage, to what point did He refer His answer?  Did He quote Roman law?  No, He quoted Genesis:

And Pharisees came up to him and tested him by asking, “Is it lawful to divorce one’s wife for any cause?”  He answered, “Have you not read that he who created them from the beginning made them male and female, and said, ‘Therefore a man shall leave his father and his mother and hold fast to his wife, and the two shall become one flesh’? So they are no longer two but one flesh. What therefore God has joined together, let not man separate.” They said to him, “Why then did Moses command one to give a certificate of divorce and to send her away?”  He said to them, “Because of your hardness of heart Moses allowed you to divorce your wives, but from the beginning it was not so. And I say to you: whoever divorces his wife, except for sexual immorality, and marries another, commits adultery.” Matthew 19:3-9

So, concerning the definition of marriage, we would do well remember its origin, respect its creator and subjugate our own desires to His decree.

Server Inventory Script

August 5th, 2009 by Steve 3 comments »

As a consultant, many times I need to quickly gain information about the Windows servers in an environment. I’ve finally put something together to try and make my life easier. It is a script that opens Microsoft Excel, sets column definitions that seem useful to me, then populates the spreadsheet with a bunch of data.  The data is gathered from every Windows server that is a member of the Active Directory domain you specify.  Specifically, it gathers:

  1. Server Name
  2. Whether the server is online (ping’able) or not
  3. OS
  4. Service Pack
  5. Manufacturer
  6. Model
  7. Serial Number
  8. Whether it is a domain controller
  9. Whether it is a DNS server
  10. Whether it is a DHCP server
  11. Whether it is a WINS server (yes there are still a few of those)
  12. Whether it is a MSCS cluster node
  13. Whether it is an Exchange server
  14. What applications are installed (excluding Security Updates and Hotfixes)
  15. Whether WMI could be connected to

Dependencies

  • Microsoft Excel (any later version is fine)
  • Sysinternals PSTools
  • Admin rights on every server in the domain (Domain Admin rights would be easiest)

I wanted to use WMI exclusively but unfortunately it is very unreliable, therefore the script heavily depends on 2 PSTools (PSInfo and PSService).  You will need to download those and place them in a directory on the PC you run the script from.

Edits

The only lines you need to edit are 15 and 16, where you enter in your domain name (follow the format example!) and the path to your PSTools directory.

'your domain below
strDom = "DC=ACME,DC=COM"
pstoolsPath = "c:\Tools\pstools"

You can download the text of the script here or a zip file with the script here.  I hope others find it helpful.  As always, use this solution at your own risk.  If you have problems with the script, comment on the post and I will help when I have time.

How To Use Windows 2008 to Host Storage for ESX

July 8th, 2009 by Steve 1 comment »

Disclaimer

Let me stress before I begin that the below configuration is for testing only.  It involves insecure settings on the Windows 2008 server so do not use this information for a production solution.

Background

In an effort to learn about ESX 4.0, or vSphere, I set up 4 VMs within VMWare Workstation 6.5.2 using the below configuration:

  • 2 VMs to run ESX 4.0.  I used the instructions at xtravirt.com (get them here) to create the VMs.
  • 1 VM to run vCenter server.
  • 1 VM to serve as a domain controller.  vCenter cannot be installed on a domain controller, hence the need for another VM.  By the way, you don’t need a domain environment for vSphere, but I wanted one to test with.

All my installs went fine.  However problems arose when attempting to use the vCenter server (OS: Windows 2008) as my NFS server.  I had used Windows 2003 in the past with no issue for a similar set up so I was stuck for awhile. Google searches revealed others with the same issue but no solutions (that I could find).  I’m happy to report I did finally get it working…steps below.  The following assumptions apply:

  1. You have already added the File Server role with the Services for Network File System (NFS) role service and that you have an NFS share created.  For a walk-thru of this go here.
  2. Your ESX host’s have a VMKernel port properly configured to allow access to the NFS server.  Confirm the configuration is correct by vmkping’ing the NFS server from the host itself.

VMKPing

Steps to enable ESX hosts to access NFS share on Windows 2008.

  1. Edit the NTFS permissions of the shared folder to allow the ANONYMOUS LOGON group Full Control.
    1. AnonymousPermission
  2. On the NFS Sharing tab click the Manage NFS Sharing button.  Check the Allow anonymous access box.
    1. NFSTabNFSAdvancedSharing
  3. Click the Permissions button.  In the NFS Permissions dialog click Add.  Select Host and enter the IP address of your first ESX host.  Set the permissions to Read/Write and select the Allow root access box and click OK.  Repeat the proceedure for your other ESX host.
    1. NFSPermissionsAddHost
  4. Click OK three times then Close.  If a warning pops up about how insecure this configuration is, clickYes.  Remember, this is for testing only.
  5. Open the Local Security Policyeditor (Start>Administrative tools>Local Security Policy), expand Local Policies, and click Security Options.
  6. Locate the Network Access: Let Everyone permissions apply to anonymous userspolicy and make sure it is set to Enabled.
  7. Reboot the NFS server.  When it comes back up you should be able to mount the NFS share from the ESX host(s) within vCenter.

Re-Use Your (or someone else’s) VBScript Code

June 20th, 2009 by Steve No comments »

How many of us have searched incessantly for “that script” we wrote/borrowed/stole 2 years back?  OK, I still do that sometimes but I have a method that drastically reduces this usually fruitless but always frustrating script-hunt.  This method leverages Windows Script Host’s capability to reference another script at execution time, simlar to the way programming languages allow you to reference an “include” file.  Basically there are 2 steps to start taking advantage of this sanity-saving technique.

Step 1 – The “Include” File

Create your “include file”.  This is simply a VBS file that has all of the reusable Functions and Subs you have found helpful over the years.  I call mine “Global.vbs”.  You can download the one I use here (rename it with a VBS extension) as a starting point, but be sure to add your additional functions/subs as needed.  Whenever you find or write a cool function/sub, make sure it is well tested then add it to your include file.  If you downloaded mine note the comments at the top which describe the functions/subs contained.  I recommend keeping this comment section up-to-date so that it is easy to see what goodness the file contains.  Once the include file is complete place it in a location that is accessible from anywhere on your network.  If you use Active Directory I suggest placing this in the sysvol SCRIPTS directory (the old NETLOGON share).  That way it will be replicated and accessible from all your domain controllers, can be updated from one place, and when called, the most “local” version will be used (thanks to AD Sites).

Step 2 – The “Main” Script

In step 1 you created an awesome repository of tried and true code.  Now to put it to use.  Create a text file called EXAMPLE.WSF and paste the following in it:

<job>
<script language="VBScript">
	option explicit
	Dim TotalRunTime
	TotalRunTime = Timer()
</script>
<script language="VBScript" Src="\\SERVER\SHARE\global.vbs"/>
<script language="VBScript">
'***************************************************************************************
'***************************************************************************************
'This is a blank script file that includes global.vbs.
'
' Version 0.1
' Author
' Arguements:
'***************************************************************************************
'************************************Insert user code below*****************************

'************************************Insert user code above*****************************
wscript.echo "Total Run Time = " & timer() - TotalRunTime & " Seconds"
</script>
</job>

Keep this EXAMPLE.WSF handy so you can use it as a template to create your scripts.  Everytime you need to write a script just make a copy of EXAMPLE.WSF and write your code between the “Insert code Here” lines.  As you write it and need to reference a function/sub that is listed in the “include” file, just reference it as though the function/sub was already in the script you are writing.  Remember that all of the reusable code from your “include” file is read in during execution time so it is all available to call.

As implied in the title of the blog entry, the main benefit of this approach to scripting is that you reuse your code…no more re-writing the same script you wrote (and lost) several times in the past.  And when you don’t have to re-write code you don’t have to re-debug all the same mistakes you made in the last several times you wrote the script.  Additional benefits include smaller scripts (you don’t have the functions/subs in your main script), and easier scripting for the VBS-uninitiated (all the hard stuff is already written…just call it).

Disclaimer - I did not invent this “Mac Daddy” process but I have used the heck out of it.  All thanks go to Tommy Mills, one of my many scripting mentors…Thanks Tommy!

What is “Good” and “Bad”?

April 2nd, 2009 by Steve 2 comments »

 

What is “good” and “bad”?  What is “right” and “wrong”?  Are these concepts merely constructs of a collective societal will?   A sort of sum of a group’s preferences with some averaging applied to come up with a generally agreed upon “standard”?  Is right and wrong based on preferences?  Let’s explore this idea.

 

One person named Bob has an opinion/feeling about prematurely ending the life of newborn puppies.  Terminating newborn puppies makes him feel good inside and he has always felt deeply that newborn puppies should not be allowed to live.  To Bob it seems like such a conventional, inner belief that he has a hard time understanding how anyone could feel otherwise.

 

The remaining individuals in Bob’s neighborhood, 10 people in all, deeply feel that prematurely terminating the life of newborn puppies is wrong.  Deeply wrong.  They have even attached harsh terms to this practice, calling it “murder” or “atrocity” or “crime”.   So the 10 individuals decide to band together to “protect the rights” of puppies.  They form a group called “Puppies are Precious” and form a written, prescriptive edict declaring that all puppies are precious and that their lives should be protected, enriched, and prolonged to the maximum degree possible.

 

One morning Bob is interrupted from his daily task of prematurely terminating the lives of a few puppies by a stern knock at the door.  With some degree of perturbation he answers the door in his blood-stained apron, knife in hand, only to find 10, first angry then increasingly horrified neighbors standing in his front yard.  A representative of the group collects himself enough to inform Bob that it is entirely, and absolutely wrong to “murder” innocent puppies and that Bob must cease and desist this “atrocious” act immediately.

 

Bob, who highly values his relationship with his neighbors is thoughtful for a moment.  Then as his desire for peace and good relations gives way to righteous indignation he answers the representative by asking “Or what?”.

 

This stuns the representative, who looks back at his fellow “PP” group members for reassurance.  After retiring into the group for a short dialog he rejoins Bob by declaring that the group would normally attempt to bring about change with neighbors through diplomacy but that the “heinous” nature of Bob’s “crime” demands that their group stop him with force if he does not willingly concede to their demands.

 

Now it is Bob’s turn to be stunned.  He had already been completely unprepared for this dialog, and now this threat of force by 10 individuals set him to stammering for a reply.

 

Immediately sensing their advantage, the group pressed Bob with further threats, and informed him that there would be a delegation that would inspect his home weekly for the next 3 months to look for signs of the afore mentioned “crime”.  Additionally a separate delegation would meet with Bob weekly to set about teaching him the ethical principle that puppy’s lives are precious.  The group sincerely hopes that Bob can be brought back into the “mainstream” through education.

 

Bob, who was outmatched by the power of the group is forced to agree to these terms, although in his heart he still “knows” that he is right.

 

Who is right?  Why would the opinion of 10 individuals be more legitimate than that of 1?  Who is it that dictates that the more powerful group’s idea is right?  Does the issue simply come down to who holds power?  Is an individual likely to be converted to a more powerful group’s opinion of right and wrong as a result of being forced to comply with their wishes?  Is it possible that the individual will retain their view and still practice their heart-felt belief insomuch as they can do so without detection by the more powerful group?   What is the opinion of the puppies?

 

Objections

==========

It seems self-evident that this view of ethics is not commensurate with human experience, or at least is lacking in precision.  With some variation, humans seem to have a “built in” concept of right and wrong and it seems to be universal.  One would be hard-pressed to find a culture where cowardliness was thought to be a virtue.  Or where lying was thought to be “good form” by the one lied to.  Or where indiscriminately taking the life of newborn puppies was thought to be “good”.  So the seemingly inherent, universal concept of good and evil in people (with some few exceptions) seems to indicate something beyond preference.  It seems to indicate a pre-programmed moral compass which directs toward a fixed point or standard.  A standard which is broader than any single person or isolated society.

 

Where does this universal moral standard come from if it is broader than the individual or isolated society?  Is it genetic and therefore a product of evolution?   It seems that many of our moral concepts lead to conclusions that are counter-productive to evolution’s driving force, “survival of the fittest”.  The fittest survives by pragmatism, not by principle.  The fittest does whatever is necessary in any given scenario to ensure their survival.  Lying, cheating, cowardliness, etc. are all completely acceptable to the pragmatist if these traits further the goal of surviving and prospering.  Any self-less actions have no place in a moral standard created by evolution.  Yet more commonly than not we approve whole-heartedly of those who perform self-less acts.  While we may not understand such acts, or may feel such acts are beyond what we could or would do, yet we seem to think of them as “good”, and many times wish we could be more like that self-less person.

 

Conclusions

===========

If the moral standard’s source is not an evolutionary process then what is it?  There are perhaps several possibilities but one plausible explanation is that there is a standard of right and wrong that is higher than human preference.  A standard that’s source is external to ourselves but that has been integrated into who we are as humans.  A standard set by a moral law giver.  A law giver with the inherent right to say to human beings, “you may do this, you may not do the other”, and with the power to integrate this standard into our being.  Following this line of reasoning, this lawgiver would most likely be the creator since the one who makes a thing is most likely to have access to the thing’s “inner programming” and who other than the creator of a thing has the right to demand that the thing adhere to a standard?

System Center Operations Manager – ACS Training

March 6th, 2009 by Steve No comments »

SecureVantage has some excellent training available on their web site for Audit Collection Services.  The training consists of a series of presentations from well respected System Center Operations Manager experts.  In fact most of the presenters are MVPs.  On a more dissapointing note, they did let a little-known slacker (some guy named Steve Ross) present on one topic…ACS DR/Failover.  You may want to steer clear of that one. 

Check out the whole series here.

OpsMgr Event Correlation – Branch Site Monitoring

December 11th, 2008 by Steve 10 comments »

I am a big fan of System Center Operations Manager 2007, but in it’s current version it has a limitation.  If your management server is at your primary datacenter and it monitors servers in a remote site, what happens if the WAN link between the two locations goes down?  Ideally your monitoring solution is smart enough to know that the branch site is unavailable and due to this condition it will cease trying to monitor the end points at that branch until the site is available again.  This capability is known as event correlation.  However I have found no way to configure this functionality in OpsMgr.  I have even posed the question on OpsMgr forums and asked OpsMgr MVPs, all to no avail.  So, necessity being the mother of invention (or creative re-utilization) I have pieced together a solution.

Assumptions:

  1. You have computer groups set up in OpsMgr for each branch site.  In my case, my branch sites are also set up in Active Directory as AD sites.  If this is true for you as well be sure to check out Cameron Fuller’s blog about setting up dynamic computer groups based on AD sites.
  2. You know the IP address of the branch site’s router.  We will be ping’ing this to check the availability of the site as a whole.
  3. You have Boris Yanushpolsky’s “rock-on awesome” script to place an entire computer group in maintenance mode (get it here).  Put his script in a folder on your management server, such as “C:\Scripts\GroupMM”.
  4. Your management server has Powershell and the OpsMgr Powershell console component installed.

How Does It Work

The heavy lifting is done by Boris’ maintenance mode script.  All this solution does is determine whether the branch site router is reachable (via our friend “Ping”).  If it is then we record that in the results file (auto-created).  If the router is not reachable then put the computer group in maintenance mode and create a tracking file with the site name (so when we run later we don’t try to put it in maintenance mode again).  The condition and action taken are recorded in the results file.  Later when the router becomes reachable again we remove the computer group from maintenance mode, delete the tracking file and record the condition and action taken in the results file.

To Implement the Solution:

  1. Create a directory on your management server for the branch availabilty monitoring script, such as “C:\Scripts\BranchSiteMonitoring”.
  2. Edit and save the BranchSiteMonitoring script (at the end of this blog entry) in the directory you just created.
  3. Create an input file called “input.txt” and place in the directory you created in step 1. This input file should list the IP address of the branch site router and the OpsMgr computer group name that corresponds to that site.  Separate these two bits of information with a “~”.  Each new IP address and computer group name should be on a new line.  Ensure there is not a blank line at the end!  The input file should look like this:

192.168.1.254~Houston Branch Site

192.168.2.254~Austin Branch Site

etc…

4.    Schedule a task on the management server to run the BranchSiteMonitoring script as often as you like.  Keep in mind the idea is to “catch” the site outage before OpsMgr does so the script can place the end points at the unavailable site in maintenance mode BEFORE getting a bunch of unneeded alerts.  I would start out with running it once every 5 minutes.

Cowardly Disclaimer:

Use this solution at your own risk.  I’ll take responsibility for my actions (like running scripts on my corporate network written by people I don’t know) and you can take responsibility for yours <g>.

The Script:

Big thanks to dm_4ever for his WMI ping function (you thought I was kidding about “re-utilization!).  If the WMI version gives you grief you can try his non-WMI version instead.

 Script Download