Tuesday, March 11, 2014

PowerShell testing empty parameters with if and $false

I just ran into the most interesting behavior.  I say that because I never ran into it before.

In many of my scripts I evaluate to see if a value has been passed in order to decide if I am going to process something.

Within my scripts it simply looks like this:

if ($VirtualMachineMigration) { }

If this parameter contains something, then act upon that something.  The reverse is to use the not:

if (!$VirtualMachineMigration) { }

If this parameter contains nothing, then do something.

Today I learned that this works all well and fine with strings, and objects, and integers, etc.  But not so well with Booleans.

Lets take a look at the following:

function EnableVMMigration
{
    [CmdletBinding()]
    param
    (
        [System.Boolean]
        $VirtualMachineMigration
    )

    if ($VirtualMachineMigration) {
        "in my If, making my next decision"
    }
    "Out of my IF"
}

That is simple enough, it accepts a Boolean parameter of VirtualMachineMigration.  Lets give it a go:

First give it a $true:

PS C:\Users\Administrator\Documents> EnableVMMigration -VirtualMachineMigration $true
in my If, making my next decision
Out of my IF

Exactly as I expected.

Now, give it a $false

PS C:\Users\Administrator\Documents> EnableVMMigration -VirtualMachineMigration $false
Out of my IF

It never even entered my if statement.  Because the If is $false, because I am sending it one – although the condition of the evaluation of ‘is $VirtualMachineMigration’ empty is actually no different than it was when it was $true.

So, what is happening?  PowerShell is simply evaluating the parameter itself, not the question of ‘is this empty’.

Tricky little shell.

So, what if I really want to check if this is empty and the possibility is either $true or $false?  (this is my first idea to work around this, I am sure that there are others)

So, lets update the function so that I truly see if the parameter is empty before deciding how to act on whether it is $true or $false

function EnableVMMigration
{
    [CmdletBinding()]
    param
    (
        [System.Boolean]
        $VirtualMachineMigration
    )

    if ($VirtualMachineMigration) {
        "making a positive choice"
    }
    elseif (!$VirtualMachineMigration) {
        "Making a negative choice"
    }
    "Out of my IF"
}

PS C:\Users\Administrator\Documents> EnableVMMigration -VirtualMachineMigration $true
making a positive choice
Out of my IF

PS C:\Users\Administrator\Documents> EnableVMMigration -VirtualMachineMigration $false
Making a negative choice
Out of my IF

Now, that works the way I wanted it to.

Friday, February 28, 2014

SCVMM Service deployment Error (22758) The system cannot find the file specified – but it is right there

I spend days on this issue and did not want to lose the ‘why’ this cost me days.

First, the details of the error:

Error (22753)

The script command with properties: Type (PreInstall), Deployment Order (20) and Parent Type (ApplicationProfile), failed to complete successfully. Refer to the errors list for more information.

Error (22758)

The guest agent encountered an exception while running a script command. Win32ErrorCode: 2147942402 DetailedErrorMessage: The system cannot find the file specified

I can definitively tell you that this error has nothing and something to do with the script being run.  And, this is the SCVMM Agent itself tossing this error, not my script.

First; the most useful log in SCVMM Service Templates is the SCVMM Guest Agent diagnostic log.  You find it buried in the OS of the VM under %ProgramFiles%\<System Center Version>\<VMM Guest Agent Version>\bin\diagnostics\VmmGuestLog.svclog

If you try to open this up with Notepad or WordPad or NotePad++ it just looks like a bunch of poorly formatted XML.  Very difficult to troll through.

However, if you use Microsoft Service Trace Viewer, you have a totally different experience.  Trace Viewer is part of Visual Studio, which you can get an Express version for free, or download it here.

Looking through this I go looking for the events that the SCVMM Job log tossed at me.

I find:

4: GetExpandedGCEErrorInfo reported The script command with properties: Type (PreInstall), Deployment Order (20) and Parent Type (ApplicationProfile), failed to complete successfully. Refer to the errors list for more information.

But not the Win32ErrorCode.

Right after the above is the following:

4: Encountered an exception for ActionItem Type: Gce, Exception: Microsoft.VirtualManager.GuestAgent.Common.GuestAgentException: Error in the application.
   at Microsoft.VirtualManager.GuestAgent.Gce.GceProcessor.GetStdErrorMatch()
   at Microsoft.VirtualManager.GuestAgent.Gce.GceProcessor.PerformPostProcessing(List`1& warnings)
   at Microsoft.VirtualManager.GuestAgent.Gce.GceProcessor.Run(IQueryCancel queryCancel, List`1& warnings)
   at Microsoft.VirtualManager.GuestAgent.AIFactory.GceActionProcessor.ExecuteActionItemSync(Boolean restarting, ActionItem actionItem, IQueryCancel queryCancel, List`1& warnings)
   at Microsoft.VirtualManager.GuestAgent.QueueManager.QueueManager.QueueProcessorThread(Object context)

This definitively tells me that it is not my script, but instead the SCVMM Agent is the one not finding the file. The best that I can determine is that that GetStdErrorMatch() being empty is the root.  But what does a positive return look like?

And, to make it worse, the script ran.  Everything worked!  And if I checked the VM all of the SCVMM artifacts from my Custom Resource were there ( %ProgramData%VirtualMachineManagerData\<one of the temp paths>).  Nothing was missing!

I spent the next few days changing the script, settings for the execution, accounts, paths, different ways to execute it.  It would work sometimes but mostly not.  This was the most frustrating part.  Every now and then I would not get the error; that small glimmer of hope and gets you frustrated and ends up driving you insane.

On the drive home last night the pieces slid together.  This was my log cleanup script.  It was deleting all of the log files that were empty (0kb).  I produce a lot of logs,  this is remote and headless execution, it could be happening anywhere but I have no console to observe anything.  You have to capture every little thing that happens and you don’t want to sort through 26 files when only the 5 with any details actually mean anything.

Not being the one that wrote the code what I am guessing is that; It appears that the output file is created, then fetched, then written back to. And my script deleted it in the middle somewhere.  Simply timing alone, milliseconds, would let it pass.  A moment of a slow disk drive on a hypervisor, possibly.

So, I removed the capturing of the Standard Out and Standard Error and all is good.  Seems like a silly little thing, right?  But again, this is remote installation, if you don’t log it you have no idea what happened.  So turning off logging was actually the very last thing I had any desire to do.

Tuesday, February 11, 2014

Adobe Reader cannot find font ArialNarrow-Bold defeated

Here is a really interesting error that I ran across and struggled with for a few days.

I needed to print out some PDF forms for folks to complete as part of a field trip with my robotics team.  All well and good enough, we are up to around form number 5, so nothing strange at all about the request.

I open the PDF to print it, and am greeted by a number of small dashes in the form where text should be and the following error message from Adobe Reader: “Cannot find or create the font ‘ArialNarrow-Bold’. Some characters may not display or print correctly.”

Well, no kidding, just look at how the characters render.

AdobeArialNarrow

All those dots and closer dots.  That is crazy.

Well, my workstation is Windows 8.  I can’t imagine at all why there would be fonts missing.  Or that someone would create a form that actually does not have an equivalent defined nor the font isn’t embedded in the form.

Anyway, off to searching.  And I find a few interesting links.

One is the Microsoft typography repository: http://www.microsoft.com/typography/fonts/family.aspx?FID=22  Very interesting stuff.  If you drill into the font, you can actually see the products it shipped with: http://www.microsoft.com/typography/fonts/font.aspx?FMID=180

So, a bit more research and I run across a hotfix for an older version of Office.  A font hotfix: http://support.microsoft.com/kb/956514

And some research at Adobe points to a historical change that happened that really makes the clues come together: http://helpx.adobe.com/creative-suite/kb/arial-narrow-unavailable-incomplete-cs.html

Oh, and It does not help that monotype has pulled all possibilities of getting the font, without purchasing it or a product that contained it.

Now for the fun part.  Where to get version 2.30 of the font or earlier.  Well, let me save you a bunch of time.  If you go back to the typography site, you see a list of products that have the font.  And then you go about fetching the media, installing, and checking the version of the font.

The oldest available that I can find is 2.30 – which is perfect.  Office XP has it.  Not Office 95, and through MSDN you can’t get Office 2000 nor 98.  And Office 2007 has the 2.35 version which includes the change that causes the break.

Copy those into your \windows\fonts folder and you are good to go.  Wait!  Nope, it still does not work.  I now blame Adobe.

Well, through piecing some Adobe behaviors together through other forum threads I discovered an interesting folder.  C:\Program Files (x86)\Adobe\Reader 11.0\Resource\Font

Copy the version 2.30 font files there.  Close Acrobat and open it again.  And suddenly you can print your PDF. 

AdobeArialNarrowFontFolder

Two days.  Poking around for a solution.  should it really be this hard?

Tuesday, January 28, 2014

Get the scripts for Update Rollup 1 for System Center 2012 R2 VMM

Update Rollup 1 for Virtual Machine Manager 2012 R2 was just released.

There are some annoyances that are fixed in here, so I know lots of folks that will be installing this.

However, one warning – take note of the release notes:

http://support.microsoft.com/kb/2904712

There is a SQL script in there that you must run on your VMM database as a step in the process of applying the Update Rollup.

I anticipate that many folks will get caught by this one, it is just as slick at the error for UR1 of SCVMM 2012 SP1 where it had to be manually uninstalled or else UR2 or later would not apply properly (but it would look like they do).

Considering that SCVMM pushes SQL DAC packs to database servers to build out Services, I am actually really surprised at the need for the additional SQL script.  It seems like these folks should know how to do this without requiring that extra step that can so easily be missed – especially by shops that no longer take the time to read the release notes for each and every update.

So, be aware and get that script.

[update 1/30/14]

My SCVMM Server automatically updated via Windows Update two days ago.

How did I find out?  I tried to deploy a VM from a Service Template and it failed with the error detail that the Host Agent on the target hypervisor was out of date.

Nothing else.

So, I then turned around and ran the SQL script on the VMM 2012 R2 database.

I had no time to learn what the symptom might be from not applying the SQL script.  There has to be one.  Some way to know.

Monday, November 4, 2013

Deploying XenDesktop using the SCVMM Service Template

The latest release of XenDesktop is now available as a Service Template for System Center Virtual Machine Manager.

I am assuming that my blog readers are already familiar with the concept of Service Templates, introduced with SCVMM 2012. 

The “Service” is where the applications and OS are separate entities, they are layered across each other and deployed as a composed entity with intact references and dependencies.  The Template is the representation of these dependencies and relationships.  The Template is ‘deployed’ into a ‘Service’.  The Service is the running machines.

For most of the past year we have been focused on simplifying the deployment of the XenDesktop infrastructure.  After all, there are enough decisions to make without having to spend one or two days installing operating systems, applications, and configuring them.  This is where the XenDesktop VMM Service Template comes in.

The whole idea is to take the monotonous tasks of deploying VMs, installing XenDesktop, configuring those infrastructure machines and reducing them to a few questions and time.  Freeing you up to do more important things.  Ant the end you can have a distributed installation of XenDesktop – the license server, Director, StoreFront, and Controller.  All connected and ready to deliver applications or desktops.

Why not give it a go?

If you just want to see what this is all about, take a look here:  http://www.citrix.com/tv/#videos/9611

If you head over to the XenDesktop download page, you will find a “Betas and TechPreviews” section.  In there you can download the XenDesktop Service Template zip package.  (The Service Template is the TechPreview not the version of XenDesktop).

http://www.citrix.com/downloads/xendesktop/betas-and-tech-previews/system-center-service-template-tech-preview.html

By the way – there are four templates.  One template to install a scaled out XenDesktop, another for an evaluation installation of XenDesktop.  You will also find Provisioning Server templates that can also support scaling out or an evaluation installation.

After downloading the package, unzip it to a convenient location, then open up the SCVMM Console, Select the Library view, and click on the Import button in the ribbon. 

You can always stop here and read the administration guide, it is short and has all the pretty screen shots that this post is missing).

Browse to the XML file in the package you just unzipped. 

Then map your generalized Server 2012 (or Server 2012 R2) VHD / VHDX to the package by selecting the pencil (a red X appears when it is mapped – don’t ask me why a red X)

Just like the generalized virtual disk, if you want SCVMM integration enabled, then place the SCVMM installation ISO in your VMM Library and select that pencil icon to create the mapping.

The Custom Resource should be uploaded from the package and contains the Citrix parts.

There is a really short import video here if you don’t want to read all of that.

After you import, you can deploy the XenDesktop infrastructure by simply right clicking the template and selecting Configure Deployment.  Answer a few pertinent questions, select Refresh Preview for SCVMM to place the machines, and select Deploy Service.  The name you give your Service will also become the name of your XenDesktop Site.

Now, go to lunch.  When you return, connect to the console of the Controller VM, open Studio, and begin publishing desktops.

You can watch a shortened version of the deployment process.

The requirements are not different than any version of XenDesktop.  There needs to be; a domain to join with DNS, a SQL Server, a VM Network from which the machines can reach those resources, a RunAs account for the (first) XenDesktop administrator, and a user account for XenDesktop to integrate with SCVMM.

As time passes you may decide that you need additional StoreFront Servers or Desktop Controller servers.  To do that, select your Service in the VMs and Services view, right click, and Scale Out.  Select the tier and go.  Additional Controller capacity is created for you and added to the Site, StoreFront requires some additional configuration so you can tailor the load balancing to your environment.

If you need to see that one, I have a video for that as well.

If you need support, you can get that in the XenDesktop forums, we will be there to help and respond to questions.

Please, give us feedback and let us know what you think.