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 has 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

The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer.

June 1, 2009 by baraholka1

While running a MSI, the Installer tried to start a service and failed, thus aborting the install. It wrote the following message to the Windows Application Event Log.

The description for Event ID ( 0 ) in Source ( PCMConcentrator ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event: The service could not determine the name of this machine. This is critical for service discovery to work, hence the service will now terminate..

The critical part of the error was in final two lines The service could not determine the name of this machine.

I chatted to Product Support for the publishers of the service and they told me that the problem was that the computer I was installing the Service on was not part of the correct Domain.

As it happens, I was installing the product on to a Virtual Machine created from a template and indeed had not specified any Domain. The VM was part of WORKGROUP. So I added the VM to the correct domain and the Service was able to start.

HTH.

Citrix Presentation Server Installation Fails: Installer Internal Error 2753 icaconf.exe. 827545c6_7013_4DE_1_8E6C_DAEE4C57F54A

May 28, 2009 by baraholka1

My Favourite GUID

I’ve been installing all the necessary components for some product testing using Citrix Presentation Server. I was given a large Powershell script that is meant to provision the Test Environment automatically but it turned out to be extremely fragile. Consequently I’ve spent a couple of days working through installation bugs and conflicts.

It came time to install Presentation Server itself and the MSI failed with the satisfyingly geeky error message in the title.

Citrix Knowledge Base and Forums gave a few possibilities for the problem:
1) Upgrading from a previous version of Presentation Server (PS) to a newer version will fail if you have upgraded your existing PS box with a newer version of the Program Neighbourhood client than comes with your XenApp Server upgrade.

2) The installation media is corrupt.

3) There is an active RDP session into the box in which you are running the install/upgrade and that RDP session is running PN.exe

None of those seemed to apply in my case.

Then a freaking genius of a colleague made a freakingly sensible suggestion. ‘Try installing Presentation Server on a clean VM image’. The purity of the revelation transported me to ecstatic visions. Yes Yes Yes!!! Clean Image! And it WORKED.

My task now was relatively simple: Retire and devise a tax-deductible religion based on this insight. After that, look at the differences between my two VM Images and by means of good old Divide and Conquer find out why Presentation Server did not install into my Test Server Image.

Forensic Deconstruction

First, I noticed that on my clean server Image the Management Console component of PS was deselected i.e. not selected for installation. So I tried that on my Test Server. No luck. Installation failed: same error.

Second, I compared the Operating System Services and running processes on the two VMs. I made the two as identical as possible in this regard by stopping Services and Processes on my Test Server that were not running on my clean Server and then tried to install. No luck. Installation failed: same error.

Third, I compared what other Citrix products I had installed on my clean Server as opposed to my Test Server. I noticed two: Access Management Console and Citrix Plug In Pack I uninstalled ACM and then tried to install PS. No luck. Installation failed: same error.

Fourth, I uninstalled Citrix Plug In Pack and then tried to install XenApp Server. Well, Pickle my Grandmother. It actually installed. Break out the Bolly!

Then I went back and installed the Management Console (just re-ran the MSI)
(Trumpets, popping corks and unrestrained hooting fill the air. HEY YOU! Put down that FERRET!)

…so its installed.

To sum up: I uninstalled Citrix Plug In Pack, then I was able to install Presentation Server. That got rid of Installer Internal Error 2753 icaconf.exe. 827545c6_7013_4DE_1_8E6C_DAEE4C57F54A

Exactly why, I don’t know. Do you think I’m a freaking genius or something ???

Powershell Installation Failure: Not Enough Storage Is Available To Process This Command

May 19, 2009 by baraholka1

Dem Bones Dem Bones Dem Drrryyyyy Bones

I’ve just started a project at a large software vendor that specialises in Virtualisation products. There are trillions of servers both physical and virtual everywhere including numerous test servers with leftover instances of various versions of operating systems. Consequently the test environment resembles a kind of Operating System graveyard. When you are assigned a server for your testing it could have the decaying corpse of almost any OS installed on it.

Learning Curve Approaching

I am a software guy so haven’t had overmuch to do with the installation, configuration and provision of virtual machines or virtualised apps, so its very much a learning curve for me to have to test Virtualisation products. Today I was required to install the necessary software for the test harness, part of which included Powershell 1.0

Powershell duly failed to install, giving the error message ‘Not enough storage is available to process this command.’

Who Ate My Disk ?

Well, my test server had a 34GB disk with only 1GB free. Powershell only requires 1.5MB to install so it didn’t really look like a disk space problem. Nevertheless with 97% utilisation I decided to free up space but oddly, by using ‘Properties’ on the folders could only identify about 16GB of actual usage.

A colleague then showed me that two .sys files were consuming 17GB between them; one belonging to the Page file and one belonging to the Hibernate process. So now I knew where my disk space was going. I freed up about 100 MB by deleting unneeded apps, but still Powershell wouldn’t install ‘Not Enough Storage’. My liver started to ache.

Which Powershell ?

Disk space was not really a good fit for a suspect anyway, so I checked that the Powershell version I was installing was compatible with the Operating System. Checking Control Panel -> System I found I had been bequeathed ‘Windows Server Enterprise Copyright 2007′ which I assumed to be Windows Server 2003 since 2007 < 2008. WRONG WRONG WRONG. ‘Windows Server Enterprise Copyright 2007′ is actually Windows Server 2008 and that already has Powershell integrated into the Operating System. You just need to enable it.

So, making that perfectly clear, you will get the Powershell Installation error ‘Not Enough Storage Is Available To Process This Command’ when you try to install Powershell on Windows Server 2008 because it already comes provisioned as a feature of the Operating System.

But seriously, what a numbskull of an error message: ‘Not Enough Storage’. How about something like ‘Feature already installed but requires enabling’ guys? That would have made my garden path significantly shorter.

Just Quietly
Windows Server 2008 can be identified by the line of text ‘Windows Server 2008′ written vertically along the Windows Start menu.

ObjectDataSource could not find a non-generic method that has parameters: . for a SelectMethod

May 7, 2009 by baraholka1

So I’ve got an ObjectDataSource with its SelectMethod set to ‘GetStuffById’ and the contract is GetStuffById(int stuffId) and the error in the title comes up.

I’m thinking ‘what the…of course it’s got parameters read the flamin’ contract!. I even had a beautiful FormParameter defined in the markup.

But I left something out. Yes, I left out the parameter NAME.
That’s why there’s a single blank space in the error message between ‘parameters:’ and ‘.’ where the list of parameter names goes.

Classic.

My markup said:

asp:ObjectDataSource ID=”stuffDataSource” runat=”server” DataObjectTypeName=”StuffDto”
SelectMethod=”GetStuffByStuffId” TypeName=”StuffService” >
SelectParameters
asp:FormParameter DefaultValue=”1″ /
/SelectParameters
/asp:ObjectDataSource

Notice the FormParameter does not have a Name attribute? Yeah. Well I didn’t until about five minutes ago.

It should have read:
asp:FormParameter Name=”stuffId” DefaultValue=”1″

And yes, I’m eating my liver.