Wednesday, April 24, 2013

The Scripting Games are about to start!

A few hours left to the 2013 Powershell Scripting Games! I am very excited because for the first time I will be taking part in such a competition. In the meanwhile, to stay focused on my objective of learning as much as possible, I am browsing the Net and reading some pretty interesting resources.

Heres' a list:
  • The two first posts by Jeffery Hicks about the evolution of Powershell toward CIM and WSMAN (post 1, post2). 
  • An article of The Scripting Guy about WMI classes related to disks (see here).
  • Another post by Ed Wilson on using Get-ADComputer (see here)
  • A post by jeff Wouters about Compare-Object (see here)
  • A post by Richard Siddaway on updating the Help for V3 (see here)
  • ... and last but not least a post by Bartek Bielawski on $Matches automatic variable

In the meantime I have just downloaded the Windows Management Framework 3  for one of my Windows 7 x64 SP1 (6.1.7601) computers and when I tried to run it quit saying 'The update is not applicable to your computer'.

The problem here is that I though I had .NET 4.0 installed on that computer and I was wrong. When I run the WMI query to verify that .NET 4 was installed I got the following result and I thought it was good:
Get-WmiObject Win32_Product | where { $ -match '.NET Framework 4'}

Name              : Microsoft .NET Framework 4 Client Profile
Vendor            : Microsoft Corporation
Version           : 4.0.30319
Caption           : Microsoft .NET Framework 4 Client Profile
Unfortunately having this is not enough. For reference, after I installed the real Full version of the .NET 4 framework, the previous query returned:
Get-WmiObject Win32_Product |where { $ -match '.NET Framework 4'}

Name              : Microsoft .NET Framework 4 Extended
Vendor            : Microsoft Corporation
Version           : 4.0.30319
Caption           : Microsoft .NET Framework 4 Extended

Name              : Microsoft .NET Framework 4 Client Profile
Vendor            : Microsoft Corporation
Version           : 4.0.30319
Caption           : Microsoft .NET Framework 4 Client Profile
Much better!

Ok, the Games are coming in about 8 hours. Go and register if you want to compare your knowledge to other Powershell aficionados. This is the link to the registration form. Tomorrow it will be too late!

Monday, April 22, 2013

New Powershell 3.0 params for Get-ChildItem and Test-Path

Regarding Powershell 3.0 new parameters, today I want to talk about something pretty new and interesting that some of you may yet not to be aware of and that could be useful for your administration tasks. The parameters I am referring to are:
  • File
  • Directory
  • Newerthan
  • Olderthan
The first two parameters are new to Get-Childitem cmdlet and are used to return either the files or the folder in a specific path. They replace the check on PSIsContainer to determine if an object is a folder or a file. Let's see an example of each:
PS C:\>  Get-Childitem c:\windows -File

    Directory: C:\windows

Mode   LastWriteTime            Length Name
----   -------------            ------ ----
-a---  26/07/2012     05:08      75264 bfsvc.exe
-a--s  19/04/2013     16:27      67584 bootstat.dat
-a---  16/03/2013     16:34       1720 DtcInstall.log
-a---  26/07/2012     06:49    2380440 explorer.exe
-a---  26/07/2012     05:08     883712 HelpPane.exe
-a---  26/07/2012     05:08      17408 hh.exe
-a---  25/07/2012     22:37      43131 mib.bin
-a---  19/04/2013     16:24       4626 PFRO.log
-a---  26/07/2012     05:08     159232 regedit.exe
-a---  25/07/2012     22:15      27120 ServerWeb.xml
-a---  16/03/2013     16:34      12813 setupact.log
-a---  26/07/2012     09:13          0 setuperr.log
-a---  26/07/2012     05:08     126464 splwow64.exe
-a---  26/07/2012     07:26        219 system.ini
-a---  26/07/2012     09:21       1585 vmgcoinstall.log
-a---  26/07/2012     07:26         92 win.ini
-a---  26/07/2012     05:21      10752 winhlp32.exe
-a---  26/07/2012     05:08      10752 write.exe

PS C:\> Get-Childitem c:\windows\logs\* -Directory

    Directory: C:\windows\logs

Mode   LastWriteTime     Length Name
----   -------------     ------ ----
d----  26/07/2012     10:04            BPA
d----  16/03/2013     16:36            CBS
d----  16/03/2013     16:48            DISM
d---s  26/07/2012     10:04            MeasuredBoot
The third and fourth parameters are new to the Test-Path cmdlet and are used to check whether a given path is older or newer than a specific DateTime object. They have been added to replace the check on the LastWriteTime property, which was far too laborious.
PS C:\> Test-Path -Path c:\windows\logs -NewerThan "April 01, 2013 10:00 PM"
As you can see the resulting output is either True or False, depending on the result of the comparison. So, if we change -Newerthan into -Olderthan for the same folder we get True:
PS C:\> Test-Path -Path c:\windows\logs -OlderThan "April 01, 2013 10:00 PM"
Now you might be wondering why I present the parameters for two different cmdlets in the same post. Well, this is because you can make use of both together to find all the files older than a given date (i.e. in order to archive them or to delete them, this is up to you).

Here's a sample one-liner that can be used to find all the files older than 5 years in two file paths:
PS C:\> 'd:\IISlogs','h:\application_logs' | Get-ChildItem -File -Recurse -Force | ? { Test-Path -Path $_.FullName -OlderThan (Get-Date).AddYears(-5) }
I hope you will find this post useful and that you are getting used to the new Powershell 3.0 syntax. Keep in mind that this is a generic one-liner that has to be customised upon your needs. If you have any question, feel free to leave a comment.

Friday, April 19, 2013

Problem staging VMWare patches due to SSL inspection

Two months ago I described a problem with downloading patches for a brand new vCenter 5.1 and VMWare Update Manager installation. Today I faced the same problem upgrading an existing vCenter 5.0 to 5.1 where the SslVerifyDownloadCertificate parameter had already been set to 0:

Download patch definitions
Web sites:;; 
hosting the patch definitions and patches cannot be accessed or have no patch data. Check the Internet connectivity.

Heres' a screenshot of this error message:

Solved (as described in the other post) by setting once again that registry key from 1 to 0.

Wednesday, April 3, 2013

Finding paths that exceed MAX_PATH with Powershell

A lot as been said and written about the infamous MAX_PATH limitation imposed by the Windows API. Still in 2013 this keeps being a major pain for Windows File Server administrators and as such has been over-discussed but never properly solved. My opinion is that, unless a major architectural rework is done at Redmond, it is up to system administrators to keep an eye on their filesystems and try to evite as much as possible to have paths going over that hardcoded maximum.

That's why I want to share the Powershell script I use to find those paths that exceed 260 characters in lenght, being 260 the value of MAX_PATH ever since.
  1. function Get-Longpaths {  
  2. <  
  3. .SYNOPSIS   
  4.   Retrieves a list of the paths that are too long for being managed with get-childitem.  
  7.   Retrieves a list of the paths that are too long for being managed with get-childitem.  
  8.   An object is returned containing the list of the paths longer then 260 characters.  
  9.   The aim of this function is to help sysadmins to handle paths which could cause the  
  10.   “System.IO.PathTooLongException“ due to their excessive length comared to what is  
  11.   supported by .NET and Windows API.  
  13. .PARAMETER Path  
  14.   The parent path that you need to recursively check.  
  16. .PARAMETER Csvpath
  17.   The name of the csv log file you optionally want to export your list of long paths to.  
  19. .EXAMPLE  
  20.   Get-Longpaths c:\  
  21.   Retrieves long path on the system partition c: and show on the current host.  
  23. .EXAMPLE  
  24.   Get-Longpaths f:\documents c:\mylogs\longpathnames.csv -verbose  
  25.   Retrieves long path inside the folder f:\documents and saves the  
  26.   output to a csv file named longpathnames.csv under c:\mylogs\.  
  27.   It also shows additional information on the task being performed.  
  28. #>  
  29. [CmdletBinding()]  
  31.     param(  
  32.         [Parameter(Mandatory=$true)]  
  33.         [string] $Path,  
  34.         [Parameter(Mandatory=$false)]  
  35.         [string] $csvlog  
  36.     )  
  38. $options = [system.IO.SearchOption]::AllDirectories  
  39. $allfiles = [system.IO.Directory]::GetFiles($path"*",$options)  
  40. $allfolders = [system.IO.Directory]::GetDirectories($path"*",$options)  
  41. $toolongcontainer = @()  
  43. foreach($file in $allfiles)  
  44.   {  
  45.   if($file.Length -gt 259)  
  46.     {  
  47.     write-verbose "Adding $file to the list of too long paths"  
  48.     $toolongcontainer  += $file  
  49.     }  
  50.   }  
  52. foreach($folder in $allfolders)  
  53.   {  
  54.   if(($folder|out-string).Length -gt 259)  
  55.     {  
  56.     write-verbose "Adding $folder to the list of too long paths"  
  57.     $toolongcontainer  += $folder  
  58.     }  
  59.   }  
  60. if(!($toolongcontainer))  
  61.   {  
  62.   write-verbose "No too long paths found. Good."  
  63.   $toolongcontainer = "No invalid path under $path"  
  64.   }  
  65. if($csvlog)  
  66.   {  
  67.   write-verbose "Exporting output to $csvpath"  
  68.   $toolongcontainer | Export-Csv -Path $csvpath -NoTypeInformation -USECULTURE -ErrorAction Stop   
  69.   }  
  70. return $toolongcontainer  
  71. }  
  73. Get-Longpaths C:\longpath -verbose  
As you can see I used the methods GetFiles and GetDirectories of the system.IO.Directory class. In particular GetFiles returns the names of files in a specified directory, while GetDirectories gets the names of the subdirectories. The cool thing with this methods is that, for some mystical reasons explained here and here, they return the full path as a string or arrays and that's all we need.

Then all the objects returned by these two methods are added as strings to a string array named $toolongcontainer for later analysis. The content of this object can be sent to a CSV file as a  record by passing the csv file path as a parameter.

Once you have this information, you can take appropriate actions such as shortening the path, deleting files and folders that exceed MAX_PATH or moving them to a shorter path. This is up to you.

If you need any clarification about this script, feel free to leave a comment and I'll be happy to answer. But remember that the easier way to get help for a function is to dot source the script then use the built-in help function this way: man Get-Longpaths  -full where 'man' is an interesting alias for get-help.

Tuesday, April 2, 2013

Powershell Scripting Games competitor guide is out

Hello folks, today Don Jones announced that the competitor guide for the 2013 Powershell Scripting Games is online. There is basically one major change compared to previous versions: peer review and voting, which means the community will contribute to choose the best scripts and script writers. OK, as I'll take part in the Games, this scares me a little, as anything new, but it is also pretty much exciting trying to convince other people that your script is worth a 5.

Feel free to review the general guidelines to choose whether to take part in the Beginner or Advanced track. And, more important, remember that the real aim of the Games is to spread the Powershell word to system administrators that have been used to using the GUI or limited command line (such as cmd and batch) for performing the daily job for more or less two decades.

If you are going to take part in the Games do not hesitate to put a little comment with your name and your ambition! And good luck.

How to register a vCenter Server with a Web Client

Today I want to write a post explaining how to solve a recurring problem when trying to access the vSphere Web Client for the first time in a freshly installed environment.

Once you have installed the vSphere WebClient, the procedure (page 21 of this VMWare doc) says that you have to register your vCenter Server to it locally on the server where the WebClient is installed. So you open a browser, for sure Internet Explorer because we suppose this is a clean environment and you shouldn't have other browsers such as Firefox or Chrome on a Windows server. Then a problem arise when you try to connect to

In fact you get a red error message saying:

"This vCenter Server is not currently registered with a vSphere Web Client. Please use vSphere Client Administration Tool (https://localhost:{port-number}/admin-app) on the machine running vSphere Web Client to register this vCenter Server."

Here's a screenshot of this error:

Following the instruction you are given by this message, you move to and another error message appear:

"To view this page ensure that Adobe Flash Player version 10.1.0 or greater is installed."

At this point you must be thinking that this is not your lucky day and you feel like deceived by VMWare  for forcing you to install Flash on your production server. Luckily, there is a workaround to this. Onto the Web Client server, open a command prompt and move to the following folder:
cd "d:\Program Files\VMware\Infrastructure\vSphereWebClient\scripts"
In there there are two files:
26/03/2013  10:04               378 admin-cmd.bat
15/02/2012  08:57             1 025
You have to run the batch (you are on Windows!):
admin-cmd.bat register\ admin password
where 'admin' is the user account used to administer your vCenter installation and 'password' is ... its password. (Note that if you get an error message saying that your SSL certificate is not approved, just press 'A' to continue). Now that you have properly registered the service, you should be able to login to the vSphere Web Client at this address:

For this last step, use a remote machine with Flash player installed.

If you wish to force the interface of the Web Client to English, use this link instead:

Also remember to set at least Read-Only permission for your users to the root of the VirtualCenter, otherwise your users might get into the 'Loading ...' bug which I described here.

Hope this helps!
Related Posts Plugin for WordPress, Blogger...