Powershell: WMI Error. RPC Server Unavailable in Xen AppServer Farm

July 29, 2009 by baraholka1

I was getting a very puzzling RPC Server Unavailable error executing a WMI call in Powershell. The call itself was as something as simple as this:

$fruitbat = get-wmiobject -class Win32_OperatingSystem -computer BRUCE

I checked various things:
BRUCE was indeed up (online) had the RPC and WMI Services running, Windows Firewall was off, had a functioning Network Adapter and IP Address. Everything looked good.

Since BRUCE lives in a XenApp Farm I decided to make sure that the Farm was configured correctly and guess what there were some Discovery Errors when I looked inside the Citrix Access Management Console.

I ran ‘Configure Discovery’ from the Access Management Console and it completed but I was still getting RPC errors.

So, out of sheer desperation I recreated my Xen AppServer Farm.
I ran chfarm on BRUCE and recreated MyTestFarm.
Then I did a chfarm on all the other servers and re-joined them to BRUCE and MyTestFarm.

And all was well. Once again the Emergency Sacrificial Ferret was returned to his cage and started munching on those Chinese Peanuts roasted in Coconut Milk he likes so much.

So, if you’re getting RPC Server Unavailable in a Citrix Xen AppServer Farm, you’ve checked everything else and you’re feeling desperate – recreate your Farm. Your Ferret will love you for it.

BUT WAIT
As you can see the success of the WMI call depends on the health of your XenApp Farm. So before recreating the Farm, try some less aggressive fixes than I did. Recreating the entire Farm is like using a Chainsaw to get a crumpet out of your toaster. Try something a little gentler first.

1) Run “Configure Discovery” on ALL your Xen AppServer Farm servers and do that last on your Data Collector so that you know the DC is aware of all the Farm Servers.
2) Check that the Citrix IMA Service is running on all your Farm servers.

You might think of some others.
All the best!

Update: 28-Aug-2009
Here’s a little ripsnorter

Powershell: Cannot run EXE. The term is not recognized as a cmdlet, function, operable program, or script file. Verify the term and try again.

July 29, 2009 by baraholka1

What you may not have realised is that you need to dotsource exes as well as .ps1 script files.

In the same way that you must prepend a powershell script with .\ in order to execute it e.g. .\ripper.ps1, you must also prepend exes with .\ if the directory containing the exe is not in your PATH statement.

I was trying to run Microsoft’s devcon utility (devcon.exe) within Powershell from a backwater directory not in my PATH like so:

PS c:\backwater> devcon

Nope. It has to be dotsourced.

This works:

PS c:\backwater> .\devcon

Dotsource your exes or stick the directory in your PATH.

Powershell WMI Access Denied When Retrieving MetaFrame_Server_LoadLevel Object

July 14, 2009 by baraholka1

This post is obscure enough for me to think it may never be read.
It was posted July 14, 2009.
Let’s see when the first read happens.

Storming the Bastille of this July 14 problem then, I am using the following escargut-wrenching Powershell WMI command to determine the load on a particular server in my XenApp farm.

$loadlevel = Get-WmiObject -Namespace root\citrix -Class metaframe_server_loadlevel -ComputerName $serverName)

Powershell was denied access. Specifically, I received the following error from the agents of the Sun King Laissez-les manger le gâteau, or in Powershell-ese Access Denied

I will not pretend that I personally debugged this issue, but how you fix it is add the user group ‘Local Administrators’ to the Administrators group of your XenApp Farm in Citrix Access Management Console.

I think what it is, is that the adding of the Access overcomes the Access Denied issue. Or something.

Powershell: Shutdown/Reboot Server using WMI. Privilege Not Held

July 13, 2009 by baraholka1

This one only took me a couple of minutes to debug, but it gave me a laugh.

Watcha Doin’ BRUCE ?
I was using the following command from within Powershell to reboot my favourite server, BRUCE

$server = get-wmiobject -computer BRUCE -class Win32_OperatingSystem
$server.reboot()

Powershell told me rack off. Specifically it was chucking an exception with Error: Privilege Not Held. Rude old Powershell.

This error had me briefly puzzled because I KNEW that the Powershell account making the WMI call had admin privileges on BRUCE.

Then I realised that the script itself was running on BRUCE. i.e. I was running a script that was trying to shut down the server on which it was running. This may not be advisable.

So I ran the script on a different server, NARELLE, and tried to reboot BRUCE from there. Surprise, surprise it worked.

In summary, you will get Privilege Not Held from Powershell WMI if you try to reboot a server on which your script/WMI call is executing. Run your script on a different machine and try again.

Other Things To Avoid
- Sawing off a branch while sitting on it.
- Smashing yourself over the head with a Fire Extinguisher.

Powershell: Variable Loses Value Outside Of Loop

July 9, 2009 by baraholka1

This never happens either.

Here is my code block modified for simplicity. NB In the actual code, “Ampersand” is a real ampersand, not the word “Ampersand”

function LoseIt($fruitBasket, $name)
{
“Ampersand”{
$numKumquats = 0
$fruitList = $fruitBasket.split(“,”)
foreach ($fruit in $fruitList)
{
$fruitname = $fruit + $name
$serv = get-wmiobject Win32_Service | where {$.name -eq $fruitName}
if ($serv.State -eq “Running”)
{
numKumquats += 1
}
write-host “Inside Loop numKumquats is ” $numKumquats
}
}
trap
{
#Exception getting Win32_Service
#scream and cry
}
write-host “Outside Loop numKumquats is ” $numKumquats
if ($numKumquats > 0)
{
MakeKumquatJam $numKumquats
}
}

The thing was, inside the loop $numKumquats was being incremented and printing out the correct values in write-host, but outside the loop, $numKumquats was always null, with the result that the function MakeKumquatJam was never called. Sob.

I “fixed” it by removing the declaration of $numKumquts outside the for loop and moving the call to MakeKumquatJam above the trap. Like so:

function KeepIt($fruitBasket, $name)
{
$numKumquats = 0
“Ampersand”{
$fruitList = $fruitBasket.split(“,”)
foreach ($fruit in $fruitList)
{
$fruitname = $fruit + $name
$serv = get-wmiobject Win32_Service | where {$.name -eq $fruitName}
if ($serv.State -eq “Running”)
{
numKumquats += 1
}
write-host “Inside Loop numKumquats is ” $numKumquats
}
}

write-host “Outside Loop numKumquats is ” $numKumquats
if ($numKumquats > 0)
{
MakeKumquatJam $numKumquats
}

trap
{
#Exception getting Win32_Service
#scream and cry
}
write-host “Outside Loop numKumquats is ” $numKumquats
if ($numKumquats > 0)
{
MakeKumquatJam $numKumquats
}

}

With the above changes the function MakeKumquatJam was called… but it had nothing to do with the for loop.

The real problem was that originally I had actually declared two variables called $numKumquats, each with different scope. The scope of the first $numKumquats was global to the entire function, the scope of the second $numKumquats variable was local to the try/trap block commencing with
“Ampersand”

Originally I thought I had declared ONE instance of the variable $numKumquats which was mysteriously losing its value after the for loop completed. No No No. I had actually declared TWO variables with different scope. What a Powershell noob boner! It would never happen to you, right?

Kumquats. Beware. They make you do stuff.

Powershell: “Failed To Connect To Server SERVERNAME” Remote SQL Server 2005 using SMO

June 18, 2009 by baraholka1

That title is a ripper isn’t it ?
It reminds me of this limerick

There once was a young man from Japan
Whose limericks never did scan.
When told this was so,
He said, “Yes, I know.
I think it’s because I try and get as many words into the last line as I possibly can.”

So I was magnificently running the following Powershell fragment:

[System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.SqlServer.SMO’)
$serverInstance = New-Object(‘Microsoft.SqlServer.Management.SMO.Server’) $MyRemoreDbServer
$MyDatabase = $serverInstance.Databases | where {$_.Name -eq $DbVariableName}

…when one day it doesn’t work, throwing up the luminous red error “Failure To Connect To Server MyDatabase”. I was shocked. Four hours later I was still shocked. It worked on a local connection but not on a remote connection.

Then, another freaking genius of a colleague (different to the last one) came in and said, “Check your Windows Firewall settings”, to which I said “How”, and he showed me.

Which is just as well because Windows Firewall was set to ON and when we set it to OFF my code fragment started working again. Huzzah!

This is the page which had the magic answer on it. I read it but only understood about a quarter of it. I’m sure you will do better. Its called “SQL Server 2005 Remote Connectivity Issue Troubleshoot” and its on a blog called SQL Protocols maintained by the Elders of Zion, Microsoft SQL Server protocols team. Fans of Aztec-Mayan Glyphs will find this page relatively easy to decipher. The repeated references to Windows Firewall didn’t mean anything to me until now.

What you specifically need to do is

1) Enable “Fire and Printer Sharing” in Firewall exception list in Windows Firewall on your remote database server.

2) Add TCP port or sqlservr.exe to Firewall exception list, either add “..\Binn\sqlsevr.exe” or add port.

OR Just turn the Windows Firewall off. If you dare.

I can haz MCSA ?

Powershell: Delete Registry Key On Remote Server

June 16, 2009 by baraholka1

Friends Of The Bitten Tadpole:

There wasn’t much in the way of examples on the greater Google for this one. One forum entry even said it was too difficult and suggested using regedit.exe, but in fact it is very easy. Look at the following example:

# Delete the Registry Key given in $deleteKey
Function DeleteRegistryKey($deleteKey)
{
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
$Hive = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $RemoteMachine)
$Key = $Hive.DeleteSubKey($deleteKey)
}

DeleteRegistryKey “Software\Microsoft\Whatever”

Too easy.

Powershell: Copy File on Remote Computer When Path Has Spaces In It

June 15, 2009 by baraholka1

Dear Imaginary Audience,

This one depleted my life force by about 37 mins, so I am figuring it might help some of you others, even though it is simple to the point of trivial.

I have a remote computer called BRUCE:
There is a file called YouLittleRipper.txt contained in the following Path:
C:\Program Files\Microsoft\Mammoth App Folder

To copy YouLittleRipper.txt from another computer NARELLE in Powershell do the following:
- Start Powershell On Narelle
$RipperPath = "\\BRUCE" + "\" + "C$" + "\"Program Files\Microsoft\Mammoth App Folder" + "\"
$Source = $RipperPath + "YouLittleRipper.txt"
$Target = $RipperPath + "OnyaGranny.txt"
copy-item "$Source" "$Target"

The file “OnyaGranny.txt” will now exist on BRUCE in ‘Mammoth App Folder”.

The secret ingredient is to put the quotation marks around the whole path after it has been constructed in the variable $Source.

You owe me 37 mins. Give us it.

SQL Server 2005 Installation From Command Line: How To Avoid General Carnage

June 12, 2009 by baraholka1

Tadpolers (or should that be ‘Biters’):

Testing on my current project require the installation of various products into Virtual Machines via Powershell scripts. Hence I am becoming more familiar with command-line execution of MSIs and SetUp.exes of various breeds.

Here’s a few issues I encountered before, during and after command-line installation of SQL Server 2005 and links to the solutions.

1. SQL Server 2005 Management Studio Not Installed
This comes about when you install Enterprise Edition on the same machine as SQL Express. Uninstall both instances (MSSQLSERVER and SQLEXPRESS plus any others you may have there) and reinstall Enterprise Edition. Management Console will be there afterwards. Promise.

Thanks to ssjaronyx4 on this thread at Proprofs

If you don’t have Managment Console present after a fresh install (i.e. SQLExpress was not there to begin with) then do a “Modify Installation’ and choose ONLY ‘Management Tools’ and ‘Business Intelligence Development Studio’ from Client Tools. Thanks to thef150 at Dev Newsgroups.

2. SQL Browser Service Not Running And Won’t Start
Quite possibly SQL Browser Service is disabled. Enable it via Surface Area Configuration Utility. Thanks to chuber on this thread at Blackthorne Discussion Groups

3. Autopeotomy During Install
My, you have had a bad time of it, haven’t you ? Unfortunately this is not fixable. Massive fail.

4. Passwords and Accounts
…such as SQLACCOUNT, SQLPASSWORD AGTACCOUNT, and AGTPASSWORD.
If possible, don’t specify them. Leave them blank and take the defaults. It’ll make your ife a bit easier…

BUT If you are installing into a Virtual Machine, however, you must specify them.

I used Network Service i.e. account name “NT AUTHORITY\NETWORK SERVICE”, password “NT AUTHORITY\NETWORK SERVICE”.

Make sure you specify those account names in double quotes just like Haidong Ji or you will suffer like a dog.

Here’s the MSDN reference ‘How To Install SQL Server 2005 From The Command Prompt’

5. Installation Display Switches
Use /qb (Quiet with basic UI) instead of /qn (Quiet with no UI).
/qb will throw up the dialogs, but without requiring user input. This way you can see how the install is progressing and if any error messages come up you will see a nice Message Box instead of having to rummage through log files.

Access LDAP Server (Active Directory) from Powershell

June 9, 2009 by baraholka1

It took me a long time to find a good page on how to access Active Directory from Powershell, but I finally found one.

Here it is: User Management, from Powershell.com.

What I was after was the bit on how to connect to Active Directory with different user credentials.

My Journey Of Pain in a bit more detail:

The Fully Qualified Domain Name of our LDAP Server is MyLDAPServer.place.room.net.

I found this out by downloading AD Explorer from the SysInternals Web Page
and doing:
File->Connect
Connect To: place.room.net
User: place\myaccount
Password: mypassword

When the connection comes up in AD Explorer you can see the name of the LDAP Server

Then I used the directions in the User Management web page above to connect via Powershell. Notice you need to pass the credentials to connect

$entry = new-object DirectoryServices.DirectoryEntry (“LDAP://MyLDAPServer/dc=place, dc=room, dc=net”, “place\myaccount”, “mypassword”)
$entry | get-member

A query like the one above returns exactly one AD entry.

Using the AD Explorer Search functionality you can find the DistinguishedName of any object in ActiveDirectory. You can also find the AD entry via Powershell using the DistinguishedName
e.g. For a particular SCP entry on my test machine:

$entry = new-object DirectoryServices.DirectoryEntry (“LDAP://MyLDAPServer/cn=MySCP, cn=MyTestMachine, CN=Computers, dc=place, dc=room, dc=net”, “place\myaccount”, “mypassword”)
$entry | get-member

There is also a DirectorySearcher object which can run AD searches and return collections of AD objects