Wednesday, September 20, 2017

Installing PowerCLI on a disconnected network

It is a constant battle working on multiple secured disconnected networks when everything is going to the cloud. What's worse its now XAAS (Everything-as-a-Service) is the new norm and I guess this means Powershell modules as well...specifically the most important one for our environment, PowerCLI.

We upgrade out vCenter environment to 6.5.2 and I figured I wanted the same PowerCLI version

I guess starting with 6.5.1 it's now a module you can get only from Microsoft PowerShell Gallery. But I want to use 6.5.2...

HINT: You can still use the 6.5.0 installer if you like, but I like using the latest greatest and starting with

There is an article that states how to do this, but I found this does not work entirely.

I have downloaded the PowerCLI using the command

Save-Module -Name VMware.PowerCLI -Path <path\to\folder>

Copied it an external drive, moved it over and copied it into my profile path (C:\Users\Username\Documents\WindowsPowerShell\Modules\). Opened a new instance of powershell and its not loaded nor is it recognized as a module.

$env:PSModulePath does state my path is one of the locations. Hmmm...

I first try to import the module manually, but I kept getting the error when loading its first dependency, VMWare.VimAutomation.Sdk:

The log4net assembly is explicitly loaded by the PowerShell because it is in the RequiredAssemblies list of the VMware.VimAutomation.Sdk.psd1 module manifest (see VMware.VimAutomation.Sdk.psd1).


After troubleshooting this over and over and reading online forums about it and getting nowhere, for shits and giggles, I tried running this command on my disconnected system, thinking it would find the modules on my profile or at lease an error I could follow:

Install-Module -Name VMware.PowerCLI

Instead I get an message saying I need to get that latest nuget. What?

I was curious, I decided to click Yes knowingly it will not work, but thought it would give me an error code I could work with:

No file information but it did give me a link....

I go to my internet connected PC type in that link. It takes me down the rabbit hole of the azure cloud

I get redirected to:

Which then I find the link for Nuget:

That link takes me to the actual dll:

Down the rabbit hole I go....

Based on this I search where this dll's get installed at on my connected system:
C:\Program Files\PackageManagement\ProviderAssemblies\nuget\\Microsoft.PackageManagement.NuGetProvider.dll

Cool. I copied the dll over to my disconnect system (using the same folder structure). Then I re-ran just to see if I get prompted again:

Install-Module -Name VMware.PowerCLI -Verbose

No nuget message but now all I get is it can't find the repository. Great....not

Obviously I'm not connected to the internet so the repository its looking for is not available. What now?

Lets install PowerCLI manually.  After trying to manually importing the VMware.PowerCLI.psd1;

Install-Module $home\Documents\WindowsPowershell\Modules\VMware.PowerCLI\\VMware.PowerCLI.psd1

It came back with dependencies that weren't install.

I import the module VMWare.VimAutomation.Sdk, success!

Run the import again...another dependencies....there are 17 more to go....

The PowerCLI does have 18 other modules that are required to be loaded first. But which one first? If you try to import the each dependencies one by one (alphabetically it will not work), they too have dependency errors. If you open the VMware.PowerCLI.psd1 file in notepad (or ISE) you will see the dependencies with their version numbers:

I thought that by running this it would auto install the modules for me...Nope

Install-Module $home\Documents\WindowsPowerShell\Modules\VMware.PowerCLI\\VMware.PowerCLI.psd1

If I run through each module in the order it specifies, they all install just fine calling each psd1 file. However Vmware.VIMAutomation.PSCloud dependency is Vmware.VIMAutomation.Cloud and Vmware.VIMAutomation.Storage requires Vmware.VIMAutomation.SotrageUtility, yet they are not in that order. I could change the order in the psd1 file, but I didn't want to mess with what VMware release.

Instead I wrote my own installer ps1 file. I wrote it to parse the required module in VMware.PowerCLI.psd1, then add it to a hashtable with its version, then find those folders and look in their psd1 file for sub dependency, then install in the appropriate order.

These are the features added to the script:
  • Find the latest downloaded PowerCLI version folder, and copy the files to the users profile Powershell directory
  • Include a progress bar for coping
  • Copy Nuget folder (located in PowerCLI version folder) to C:\Program Files\PackageManagement\ProviderAssemblies
  • Disable CEIP
  • Copy a modified version of Initialize-PowerCLIEnvironment.ps1 to the users profile PowerCLI directory
  • Copy a icon to the users profile PowerCLI directory
  • Create PowerCLI desktop shortcuts, x86 and x64 (like the installer did, pointing to Initialize-PowerCLIEnvironment.ps1  and using the icon)
  • Load PowerCLI when done. 
The difference between old installer, it used to copy the modules to the C:\Program Files (x86)\VMware\Infrastructure\PowerCLI\Modules, add Initialize-PowerCLIEnvironment.ps1 to theC:\Program Files (x86)\VMware\Infrastructure\PowerCLI\Scripts folder, a a startmenu and desktop shortcuts to that scripts for 32-bit and 64-bit Powershell and add an entry into the PSModulePath system environment variable. 

You will also need to have a copy of nuget with the saved version of PowerCLI. The folder structure should look like this:

If there is a later version that comes out, the script does detect that folder or you can update the variable (line 4)

$LatestModuleVersion = ''

You can get the PowerShell script on github (updated 2/8/2019): PowerCLIInstaller

Coming soon...version 10

Monday, September 11, 2017

OSD Computer Name Prompt

I work with a lot of Microsoft products, one of my favorite is Microsoft Deployment Toolkit and System Center Configuration Manager, otherwise known as MDT and SCCM (Sick-em boy). My favorite part is customizing the Windows Operating System. In my company, I work with the latest. Windows 10/SCCM 2012 R2 (1511)...yes there is a later one.

What I enjoy is customizing Task Sequences. Writing PowerShell GUI's to control variables. Yes I know SCCM with MDT integrated and using its built in UDI wizard does all this for you, but what fun is that?

Here is a PowerShell I wrote to prompt for a computer name.

I have tested this against most of our Dell Systems and it does come back with the correct information. The cool thing is I loaded all the images as binary so it will load the proper image when prompted. Obviously as newer models come out; they too would need to be added.

Here are some things it checks
  • Chassis types
  • Check current name if MININT (prompt)
  • Name Validation check

To get SCCM to prompt the computer name correctly, you will need a few prerequisites.
  • If your using the SCCM (1511) and its latest ADK, be sure to provision a new Boot image so that the WinPE is matched and apply the hotfix: 3143760
  • To allow this script to be interactive, copy the ServiceUI.exe and TSProgressUI.exe from the MDT's <DeploymentShare>\tools\x64 folder (can also be found under the MDT installation folder in Templates). Add it as part of the script package. 
  • Add Run Command line in Task sequence. Add the package to is and run the command like this: ServiceUI.exe -process:TSProgressUI.exe %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File Set-OSDComputerName.ps1

The script can be found here: Set-OSDComputerName.ps1

This is very basic script but it has potential to be more...

Friday, September 8, 2017

PowerCLI Datastore Uploader GUI

Since VMware is forcing the webgui for their vSphere client; you will require the vSphere plugin to be able to upload files to the datastore. however the plugin doesn't work on every browser; Chrome and IE are the only ones I found that works...sometimes.

However, there are other ways to accomplish this: PowerCLI. The task isn't to hard; VMware has a KB on how to do it.

Basically you need to connect to the vcenter server, get the datastore and folder (if needed), map a PSDrive to that datastore, then run the Copy-DatastoreItem command. Simple right? It is for an experienced administrator. But I like to make things even simpler; why not build a UI for it using XAML and PowerShell?

Here we go again....

This simple form will check if PowerCLI is installed, if not, then either check a specified network directory for the module or get the latest from using NuGet 

Since I work on disconnected networks; the network share is useful for our environments

It will also store the last used vCenter/IP in a file under your temp directory. I thought about making a dropdown list for it for multiple vCenter scenarios.  

The progress bar in the UI does not work yet. I am still working on a runspace for it so it doesn't lock up the menu; however if you will see the progess in the Powershell CLI or ISE

This form can be found on

Oh the fun things you can do with powershell....