Friday, November 29, 2013

Cisco UCS C220 C-series serial numbers

Note: this post originally did not include the correct cURL commands.  Blogger does not allow < or > characters in posts without HTML encoding, so my hasty copy and paste of  the raw script excluded many details.  Sorry for the confusion. 

After a Cisco UCS C220 server was rebuilt piece by piece by TAC and then ultimately declared DOA, I was requested by our Smartnet manager to retrieve all the serial numbers for all the minor components. Because it was a stand alone rack mount server, I did not have UCSM available to pull the information.  I was also disappointed to find CIMC did not provide the serial numbers for all the components.

Outside of disassembling the server, it seems then that the UCS XML API interface was my answer.

By the time I managed to find all the class IDs of all the components and get a script working, we found the serial numbers on packing labels, a much simpler solution.  For those interested in some real UCS XML API examples, below is a snippet of a script I was putting together.

I was using Strawberry Perl from http://strawberryperl.com/ on MS Win7 for scripting and curl from http://curl.haxx.se/dlwiz/ for the communication with the UCS XML interface.

#! perl

use 5.010;
use strict;
use warnings;

my $ucsip = 'PUT YOUR UCS SERVER IP ADDRESS HERE';
my $ucsuser = 'PUT YOUR UCS ADMIN USERNAME HERE';
my $ucspassword = 'PUT YOUR UCS ADMIN PASSOWRD HERE';
my $cookie;

# print info re: script
sub print_header {
print "####################\n";
print "#\n";
print "# Get serial numbers from the UCS server\n";
print "# and it's components\n";
print "#\n";
print "# Ray Maslanka 11/29/2013\n";
print "#\n";
print "####################\n";
}

# log into UCS server, get and return cookie
sub curl_ucs_login_and_get_cookie {
    my $cookie;
print "Logging into UCS via web...\n";
# use curl to return login info and redirect stderr to stdout via 2>&1
my $curl = `curl -d "<aaaLogin inName='$ucsuser' inPassword='$ucspassword'></aaaLogin>" https://$ucsip/nuova -k 2>&1`;
print "Finding UCS cookie...\n";
if ($curl =~ /(outCookie=")(.{47})/){ # look for stuff starting with outCookie=" and then any 47 characters
print "Found cookie: $2\n"; # throw confirmation on screen
$cookie = $2; # put the regex in a variable to return
} else {
print "Can't find a cookie\n"; # something's bad, add some error checking
}
return $cookie;
}

# get UCS chassis serial number
sub curl_ucs_chassis_serial {
my ($cookie) = @_;
my $serial;
print "Getting chassis sumary from server...\n";
my $curl = `curl -d "<configResolveClass cookie='$cookie' inHierarchical='false' classId='computeRackUnit'/>" https://$ucsip/nuova -k 2>&1`; # use curl to return login info and redirect stderr to stdout via 2>&1
print "Finding chassis serial number...\n";
if ($curl =~ /(serial=")(.+?)(")/){ # look for stuff starting with serial=" 
print "Found chassis serial: $2\n"; # throw confirmation on screen
$serial = $2; # put the regex in a variable to return
} else {
print "Can't find a chassis serial number\n"; # something's bad, add some error checking
}
return $serial;
}

# get power supply serial numbers
sub curl_ucs_ps_serial {
my ($cookie) = @_;
print "Getting power supply details from server...\n";
my $curl = `curl -d "<configResolveClass cookie='$cookie' inHierarchical='false' classId='equipmentPsu'/>" https://$ucsip/nuova -k 2>&1`; # use curl to return login info and redirect stderr to stdout via 2>&1
local $/ = undef;
print "Retrieving power supply serial...\n";
while ($curl =~ /(serial=")(.+?)(")/g){
print "Found power supply serial: $2\n";
}
}

# get HDD serial numbers
sub curl_ucs_hdd_serial {
my ($cookie) = @_;
print "Getting HDD details from server...\n";
my $curl = `curl -d "<configResolveClass cookie='$cookie' inHierarchical='false' classId='storageLocalDisk'/>" https://$ucsip/nuova -k 2>&1`; # use curl to return login info and redirect stderr to stdout via 2>&1
local $/ = undef;
print $curl;
print "Retrieving HDD serial...\n";
while ($curl =~ /(driveserialnumber=")(.+?)(")/g){
print "Found HDD serial: $2\n";
}
}

# log out of UCS server
sub curl_ucs_logout {
my ($cookie) = @_;
print "Logging out of UCS via web...\n";
# use curl to return login info and redirect stderr to stdout via 2>&1
my $curl = `curl -d "<aaaLogout inCookie='$cookie'/>" https://$ucsip/nuova -k 2>&1`;
print "Logged out.\n";
}

# run the program
print_header();
$cookie = curl_ucs_login_and_get_cookie ();
curl_ucs_chassis_serial ($cookie);
curl_ucs_ps_serial ($cookie);
curl_ucs_hdd_serial ($cookie);
curl_ucs_logout ($cookie);


I hope this serves as a starting point for someone.  It at least demonstrates basic techniques for logging in, retrieving and using the UCS 'cookie', retrieving component information, finding interesting things via regex in perl, and logging off.

If you happen to finish this so all the serial numbers are retrieved, please link to a location where others may benefit from it.

Thursday, November 21, 2013

Cisco Unity Connection Single Inbox 401 Authentication Errors - Windows Authentication and NTLM

After setting up a new Unity Connection 9 cluster to integrate with Exchange 2010, I ran into an issue with the authentication failures when running the test on individual Unified Messaging Accounts.  Running the test against the Unified Messaging Service passed, but this typically only verifies basic network access, domain name resolution and access to the Exchange EWS interface.  The Single Inbox feature will fail if the users' Unified Messaging Accounts can't authenticate to Exchange.

The "Unified Messaging Guide for Cisco Unity Connection Release 9.x" integration guide is quite good and covers about all the scenarios I've ever run into. Follow the guide, and all of the guide, and you should be in good shape.

Following that during a pretty typical setup (a single Exchange 2010 CAS server and another 2010 mailbox server with no DAG), I had an issue where testing the Unified Messaging Accounts failed with a "Failed accessing xxx@ayz.com Diagnostic=[] Verb =[] url=[] request=[] response[]" message.  It is a 401 error, pointing to basic authentication against Exchange issues.

Basic troubleshooting steps, found in just about every Unity Connection gude are:

Check the authentication method on both sides. Check settings in Internet Information Services (IIS) for both AutoDiscover and EWS.
- This was confirmed to be NTLM and HTTPS, under both EWS and Autodiscovery



Try different UM messaging account name formats (i.e. NAME, DOMAIN\NAME, NAME@DOMAIN).
- Tried every combination of names
Reset the UM messaging account password, and enter the password again on Unity Connection.
- Verified name and password via OWA
The UM account should not have a mailbox.
- Verified no Exchange mailbox with admin.
- Another nice method to confirm this again using OWA to check the username and password above.  You should be returned an error indicating there is no mailbox for the user.

Ultimately the issue was that assumptions were made that since Windows Authentication was enabled in Exchange in the EWS and Autodiscovery areas, that NTLM was enabled. The names are commonly interchangeable, but if you are not savvy in Microsoft technologies you may not realize NTLM is technically just a provider available under Windows Authentication.

The fix: Once you find Windows Authentication is enabled, you need to verify NTLM is added as a provider under Windows Authentication.


After losing hours checking and rechecking settings in Unity Connection, grepping Unity Connection logs for anything telling beyond the 401 error, rechecking Exchange settings and the service profile user roles, and furious Googling, my only consolation is that there appears to be an abundance of confusion by Exchange admins regarding this topic and how to effectively set it up in various scenarios.

FYI, while bashing around in Exchange looking for clues, we found some errors that look rather concerning.  Microsoft indicates those are "expected behavior".


Nice.