Archive

Archive for the ‘Scripting’ Category

VMware vSphere 5–Using Image Builder For Custom Installation

August 19, 2011 13 comments

Hard to believe the vSphere 5 release is coming down the pipe. In anticipation of the official availability of the bits for use and VMworld 2011, I thought it would be a great idea for everyone to get their house in order and prep for deploying vSphere 5.

One of the cool new features with the vSphere 5 release was the inclusion of new PowerCLI functions called Image Builder.

Image Builder allows VMware Admins to customize their installation media by adding and removing components. These components, called VMware Infrastructure Bundles (VIBs), comprise the base image, drivers, CIM providers, and other necessary components to make the vSphere go-‘round. Plus, 3rd party vendors can release VIBs in the future for new devices, providers, or whatever (can someone make a Minesweeper VIB?). This results in:

  1. VMware not needing to keep updating just to add code for new devices.
  2. VMware Admins no longer need to kludge through cramming the driver support for 3rd party products using Linux-based utilities and concepts (although, good job for knowing how to do it)
  3. VMware Admins can create a single custom installation with the appropriate drivers without having to install ESXi on a host and immediately patch to add the components.

As mentioned above, Image Builder is included with the latest and greatest version of the PowerCLI utilities… well… the latest and greatest vSphere 5 PowerCLI utilities. So, don’t rush out and download right now.

Note: When installing the new PowerCLI for vSphere 5 over an existing PowerCLI installation, you may find that the Image Builder cmdlets do not appear to be available. If this is the case, be sure to uninstall ALL PowerCLI installations on your workstation prior to installing the new PowerCLI. I ran into this problem during the installation of the pre-release bits and it drove me crazy. Heck, why not just uninstall first to be on the safe side?!

Image Builder introduces two new terms to our VMware verbiage

  1. VIB – (as mentioned above) bundles of files that can comprise any base image, driver, CIM provider, or another component. VIBs are certified by VMware and fit a very specific format.
  2. Depot – A location where Image Builder can find installation components (aka – an offline bundle). An offline bundle is just a .zip file containing the installation files for a specific version of ESXi. These can be downloaded from the vSphere download page (typically, you are provided with the option of a .iso or .zip download of the media – the .zip is the offline bundle/depot). However, a depot can also be a URL to an offline bundle!!! During Image Builder sessions, multiple depots can be added to a session.
  3. Profile – A profile is the entity that comprises the image you are working with. Offline Bundles contain multiple profiles that can be used as a basis to copy. The profile, essentially, tells Image Builder which components to pack into a custom installation.
    Finally, Image Builder understands that creating a custom image does not just involve adding and removing VIBs. Rather, you also need some way to get the custom image out in a usable format. Image Builder allows for the export of the custom image to an offline bundle (.zip) or a usable CD/DVD image (.iso). The offline bundle

So, now that we know what Image Builder does and some new terminology, let’s get down and dirty with creating a new Image Builder custom installation!

Procedure

  • Start up PowerCLI

image

  • Connect to a depot
    • This example will use a locally saved .zip file.
    • Command: Add-EsxSoftwareDepot –DepotUrl C:\Downloads\VMware\Depot\vmware-ESXi-5.0.0-381646-depot.zip

image

  • The offline bundle contains a number of profiles. These profiles are read-only and cannot be edited. However, that does not mean that it cannot be copied to a new profile and customize the copied profile!
  • Get a list of the available depot profiles:
    • Command: Get-EsxImageProfile

    image

    • As you can see, we have two profiles: ESXi5.0.0-381646-no-tools and standard.
  • Create a copy of a profile
    • Command: New-EsxImageProfile –CloneProfile ESXi-5.0.0-381646-standard –Name “Custom_vSphere5_Installation”

image

  • Now that the profile has been copied, it is time to wreckcreate a new custom installation. First, let’s check on which components are included in the Depot added earlier.
    • Command: Get-ESXSoftwarePackage

    image

    • Note: This will load all software packages for all depots loaded in the session.
    • Each of the packages listed are VIBs! (NEAT!!!)
  • At this point, the question becomes: What is it about the default installation that you do not like? Are you missing some drivers/VIBs? In most instances, you are going to be missing some VIBs. However, there may be a need to remove a VIB for some reason. In the next step, we will be removing a VIB from the custom profile.
    • Note: You are the master of your universe. This example only shows you how to do something. I do not suggest you removing the VIB from the custom profile unless you know you need to. If you remove the VIB and screw up your environment, you only have yourself to blame because you are the master (right?!).
    • Note:The availability of 3rd party VIBs prior to vSphere 5 release is provided by the 3rd parties themselves. I do not have a connection to a 3rd party that could provide a VIB (wamp wamp wamp). So, I will include the command to add one. Once a VIB is available to me, I will update the post.
    • Command (Add a VIB): Add-EsxSoftwarePackage –ImageProfile Custom_vSphere5_Installation
    • Command (Remove a VIB):  Remove-EsxSoftwarePackage -ImageProfile
      Custom_vSphere5_Installation -SoftwarePackage sata-sata-promise

image

  • Alright, we have a depot, copied an existing ImageProfile, and messed with the clone so it looks like we want it to. Now, we need to get the profile in some form that we can do something with. How about exporting it?! Fantastic idea. Let’s do it!
  • The customized profiles need to be exported in a format that can be used for installation. Otherwise, you just wasted precious time and bandwidth on something that just dead-ended. Recall that we have 2 options for exporting:
    • ISO – Traditional disk image. These are burned onto CD/DVD media and ESXi can be installed.
    • ZIP – These can be stored on network locations and used for PXE installations, VUM upgrades, and a basis for future Image Builder customizations.
  • Exporting as a .ZIP or .ISO is as simple as changing a value and extension in the PowerCLI command:
    • Command (ISO): Export-EsxImageProfile –ImageProfile Custom_vSphere5_Installation –FilePath C:\downloads\vmware\depot\Custom_vSphere5_Installation.isoExportToIso
    • Command (ZIP): Export-EsxImageProfile –ImageProfile Custom_vSphere5_Installation –FilePath C:\downloads\vmware\depot\Custom_vSphere5_Installation.zipExportToBundle

image

  • Recall that earlier, we wanted to remove the ‘sata-sata-promise’ VIB from our customized installation media? (I would suggest going back a little bit in the post to refresh your memory). This is a great time to make sure it was removed.
    • Browse to the .zip location in Windows Explorer and open the .zip file.image
    • Browse to the ‘vib20’ directory.

image

    • Look around for ‘sata-sata-promise’ VIB. Can you find it?

image

    • Nope! It’s not there! Talk about customization!

At this point, you have viable installation media to streamline your installations and save you time and headaches.

Thanks VMware for the awesome utility. Happy customizations

Advertisements

Scripting: PowerCLI–Adding New Datastore

April 22, 2011 Leave a comment

Recently, I came up with a need to add a new NFS datastore to one of our datacenter clusters. The NFS location holds our ISOs for VM building. The cluster is not huge by any means, but I thought it would be worth taking the time to script it out.

In the name of community, sharing, and helping people out, I present… My script!

# Connect to your vCenter instance $vcenter = Connect-VIServer -Server vcenter.domain.local -User Administrator -Password supersecretadminpassword # Connect to the proper cluster managed by vCenter $cluster = Get-Cluster CluserName # Get the hosts inside of the specific cluster $clusterhosts = $cluster | Get-VMHost # Iterate through the group of VM hosts and perform an action on each host # In this example, we will be adding a new datastore foreach ($esxhost in $clusterhosts) { # Create the new datastore on the ESX/ESXi host. New-Datastore -VMhost $esxhost -Name "ISOStore2" -Path "/mnt/isostore" -Nfs -NfsHost nfsserver.domain.local -ReadOnly } #Disconnect the open session from the vCenter server Disconnect-VIServer -Server $vcenter

While I know this may seem a little basic, the fact is that it provides a great start for some PowerCLI scripting and may save you some time in connecting the datastores to the cluster hosts like it did for me.

Happy scripting!

Growing Pains–Network Scaling And Maturation

When I signed up with my current employer around 8 years ago, the world was a different place. We did not have much of a budget, so we relied on some creative thinking and duct tape to get the job done. The network was a much simpler place too. Every office had their own local servers and WAN traffic definitely fit a simpler profile. Planning for the future was more targeted at which products provided the most functionality at the lowest (or no) cost.

However, that was then and this is now. Suddenly, we have budgets and business sees value in investing in a cost-center, like IT. The business is growing. More and more traffic is passing over the WAN and the profile has changed drastically. Voice traffic, ICA/RDP, backup needs, and just plain more data is increasing the load on the network. Plus, we have new offices opening in places where getting a static IP address is extremely expensive and not realistic.

The network was designed a decade ago and it is becoming time to remodel so we can continue to grow. The issue becomes how. Which change is going to provide the biggest bang for our buck?

We have the backing and we believe we have made some core infrastructure purchases that allows us to operate right now and grow into the future.

So… where do we go from here?

– Dynamic Routing Protocol: Static routes have been great as we use a hub-and-spoke model for the time being. However, as we expand into China and Europe, the networking design will need to change and routing will become more and more important. Something like EIGRP will probably be the best fit for us.

– Inter-office communications: Some offices have MPLS connections. Others do not… so, their communications travel all over the world to reach other offices. Being able to bring up VPN tunnels on demand to facilitate more point-to-point connectivity is going to be important. Hello DMVPN. Sure, I can create VPN configurations on each office router for other office routers, but that becomes increasingly difficult and monotonous as a new office comes onboard and the branch offices can only handle so many connections.

– Geographic routing blocks: Conceptually, just having geographic regions in the same IP addressing area makes for simpler routing. That means re-IPing a handful of offices to meet the needs.

– Regional hubs: Does it make sense to aggregate core services in a single location or create regional hubs and focus on higher performing hub-to-hub communications. I believe the answer is ‘Yes’!

All of this is really showing me a brief glimpse into the pains and considerations that really need to take place to create a more mature networking environment. Concepts like:

– Router hardware limitation (CPU availability, encryption offloading, etc…)

– Router limitations impact on network throughput

– Resiliency design

– Limitations and Advantages of various routing protocols

– Packets Per Second (versus they typical Mbps style measurement)

– plus much more!

Based on my research, this is the next logical step for us to move. I am sure there are 1 million other ways to go (always open to comments). But, as long as I try to be forward looking and pay more attention to the little details, we should be good to go!

Implementing the options from above sounds like a lot of fun. My inner geek is squee’ing with excitement. Hopefully, these projects will turn into reality and we can begin using a smarter, larger, and more robust network in the near future.

PowerShell – Workstation NIC Settings

September 20, 2010 Leave a comment

Recently, we found a need to try and figure out why some workstations in a remote office were performing abysmally. The office, located in China, is notorious for some amazingly awful wiring in the office… most of it is actually run through some crummy conduit, encased in the concrete floor. The rest of the wiring is run in the plenum and all signs point to rats being in the area (droppings and damaged other fun “chewed” things).

So, rather than ask everyone to leave their machines turned on over night and remote control them, I thought that a nice WMI script via PowerShell would be in order.

This script actually led to a fairly interesting learning moment about NIC settings in the OS.

So… here’s the script (notice that it is similar to the last script. I like having a framework script to use for these kinds of things):

### # Search through AD for listing of workstations in HKG ### $strWorkstationList = @() # Connect to the Domain at the LDAP location specified $ou = [ADSI]"LDAP://ou=HKG,ou=Workstations,DC=domain,dc=local" # Parse through the objects in the OU location for devices that are described as "computer" ForEach ($child in $ou.psbase.Children) { if ($child.ObjectCategory -like '*computer*') { #Write results to the screen for diagnostic purposes #Write-Host $child.Name #Append the results to the strWorkstation string $strWorkstationList += $child.Name }#end if }#end for each loop ### # Parse through the list of workstations from the OU and look for NIC information from them (they need to be online) ### Write-Host "Begining to parse through the workstation list and locate NIC information" Write-Host $strWorkstationList # Ping the host to ensure that it is available on the network. # NOTE: If the firewall is configured to disallow ICMP, it will appear to be down and not be checked. # NOTE to the NOTE: if the firewall is configured to disallow ICMP, it is likely WMI is disallowed as well. ForEach ($serverName in $strWorkstationList) { try { $ping = new-object System.Net.NetworkInformation.Ping $Reply = $ping.Send($serverName) #Write-Host "Ping to " $serverName " is " $Reply.status if($Reply.status -ne "Success") { Write-Host $serverName " not responding on the network -- Status: " $Reply.status } else { Write-Host $serverName " is responding on the network -- Status: " $Reply.status $Reply.RoundtripTime "ms" Write-Host "Connecting to " $serverName # Connect via WMI to the workstation ('aka - $serverName) $NicConfig = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $serverName -ErrorVariable $exceptionVariable $myCol = @() # Parse through each NIC on the workstation (since they are configured with multiple) ForEach ($Nic in $NicConfig) { # If the NIC has an IP address assigned If ($Nic.IPAddress -ne $null) { # Define the object holding the output per NIC $myObj = "" | Select-Object Description, DHCPEnabled, IPAddress, IPSubnet, DefaultIPGateway, DNSServers, WINSServers, NICModel, SpeedDuplex # Collect values for the NIC $myObj.Description = $Nic.Description $myObj.DHCPEnabled = $Nic.DHCPEnabled $myObj.IPAddress = $Nic.IPAddress $myObj.IPSubnet = $Nic.IPSubnet $myObj.DefaultIPGateway = $Nic.DefaultIPGateway $myObj.DNSServers = $Nic.DNSServerSearchOrder $myObj.WINSServers = $Nic.WINSPrimaryServer,$Nic.WINSSecondaryServer # Connect to the registry on the remote machine in order to determine the duplex status (stored differently depending on NIC manufacturer). # Stored in the registry based on device manufacturer ID $registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $serverName) $baseKey = $registry.OpenSubKey("SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}") $subKeyNames = $baseKey.GetSubKeyNames() ForEach ($subKeyName in $subKeyNames) { $subKey = $baseKey.OpenSubKey("$subKeyName") $ID = $subKey.GetValue("NetCfgInstanceId") If ($ID -eq $Nic.SettingId) { $componentID = $subKey.GetValue("ComponentID") If ($componentID -match "ven_14e4") { $myObj.NICModel = "Broadcom" $requestedMediaType = $subKey.GetValue("RequestedMediaType") $enum = $subKey.OpenSubKey("Ndi\Params\RequestedMediaType\Enum") $myObj.SpeedDuplex = $enum.GetValue("$requestedMediaType") } ElseIf ($componentID -match "ven_8086") { $myObj.NICModel = "Intel" $SD = $subKey.GetValue("SpeedDuplex") $enum = $subKey.OpenSubKey("Ndi\Params\SpeedDuplex\Enum") $myObj.SpeedDuplex = $enum.GetValue("$SD") } ElseIf ($componentID -match "b06bdrv") { $myObj.NICModel = "HP" $SD = $subKey.GetValue("req_medium") $enum = $subKey.OpenSubKey("Ndi\Params\req_medium\Enum") $myObj.SpeedDuplex = $enum.GetValue("$SD") } Else { $myObj.NICModel = "unknown" $myObj.SpeedDuplex = "unknown" } } } $myCol += $myObj } } $myCol }# End if(workstation successfully pings test) } # End try catch [SystemException] { $var += 1 }# End Catch [DotNetMethodException} } #End ForEach ($serverName in $strWorkstation) Write-Host "Completed parsing through the workstation list and locating NIC information"

The NIC guts of this script is thanks to: http://www.peetersonline.nl/index.php/powershell/gather-nic-properties-including-speed-and-duplex/#more-51

The learning part (in addition to some more WMI and PowerShell scripting) dealt specifically with where the settings for the NICs could be found. I guess I never realized that the settings would be kept with each vendor’s registry location on the server. I guess I thought, perhaps a little naively, that there would be a registry section for the defined interface that contained this information. So, that would explain the “ForEach” logic in the heart of the script that looks for the NICModel, opens a specific registry location, and pulls the results from there. Good times!

Categories: Scripting Tags: , , ,

PowerShell – Locate Installed Printers On Windows Servers

September 17, 2010 Leave a comment

Recently, there was a need for us to gather a listing of the printers that we have deployed on our File and Print Server servers. Being a fairly distributed environment, a lot of time could have been spent logging into each server and manually gathering the data. However, this was a great time to get my feet wet and have some PowerShell/WMI fun.

Out of correctness, I would like to note that this script is Frankenstein-ish script from sources all over the Internet. Since I am not trying to do anything all that difficult, piecing together the framework script and filling in the blanks where needed is an awesome way to go. Thanks to the people online for sharing your knowledge.

Without further ado:

### # Search through AD for listing of workstations in HKG ### $strWorkstationList = @() # Connect to the Domain at the LDAP location specified $ou = [ADSI]"LDAP://ou=FPS,OU=Servers,DC=domain,dc=local" # Parse through the objects in the OU location for devices that are described as "computer" ForEach ($child in $ou.psbase.Children) { if ($child.ObjectCategory -like '*computer*') { #Write results to the screen for diagnostic purposes #Write-Host $child.Name #Append the results to the strWorkstation string $strServerList += $child.Name }#end if }#end for each loop ### # Parse through the list of FPS Servers from the OU and look for Printer information from them (they need to be online) ### Write-Host "Beginning to parse through the FPS Server list and locate Printer information" Write-Host $strServerList # Ping the host to ensure that it is available on the network. # NOTE: If the firewall is configured to disallow ICMP, it will appear to be down and not be checked. # NOTE to the NOTE: if the firewall is configured to disallow ICMP, it is likely WMI is disallowed as well. ForEach ($serverName in $strServerList) { try { $ping = new-object System.Net.NetworkInformation.Ping $Reply = $ping.Send($serverName) #Write-Host "Ping to " $serverName " is " $Reply.status if($Reply.status -ne "Success") { Write-Host $serverName " not responding on the network -- Status: " $Reply.status } else { Write-Host $serverName " is responding on the network -- Status: " $Reply.status $Reply.RoundtripTime "ms" Write-Host "Connecting to " $serverName # Connect via WMI to the workstation ('aka - $serverName) $printerConfig = Get-WmiObject -Class win32_printer -ComputerName $serverName -ErrorVariable $exceptionVariable $myCol = @() # Parse through each NIC on the workstation (since they are configured with multiple) ForEach ($printer in $printerConfig) { # Define the object holding the output per NIC $myObj = "" | Select-Object Description, DeviceID, DriverName, InstallDate, Local, Network, PortName, ServerName, ShareName # Collect values for the NIC $myObj.Description = $printer.Description $myObj.DeviceID = $printer.DeviceID $myObj.DriverName = $printer.DriverName $myObj.InstallDate = $printer.InstallDate $myObj.Local = $printer.Local $myObj.Network = $printer.Network $myObj.PortName = $printer.PortName $myObj.ServerName = $printer.ServerName $myObj.ShareName = $printer.ShareName $myCol += $myObj } $myCol }# End if(Server successfully pings test) } # End try catch [SystemException] { $var += 1 }# End Catch [DotNetMethodException} } #End ForEach ($serverName in $strServer) Write-Host "Completed parsing through the Server list and locating Printer information"

Categories: Scripting Tags: , , ,