Reorganization
Reorganization of resources to better prepare the repo for growth
This commit is contained in:
1 parent
24348d17c1
commit
af35a7227c
12 files changed
No files matched your search
@@ -0,0 +1,36 @@
|
||||
function Check-Tools {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Graf
|
||||
Organization: VMware
|
||||
Official Blog: blogs.vmware.com/PowerCLI
|
||||
Personal Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This will quickly return all VMs that have VMware Tools out of date
|
||||
Along with the version that it is running
|
||||
.Example
|
||||
Check-Tools -VMs (Get-VM)
|
||||
.Example
|
||||
$SampleVMs = Get-VM "Mgmt*"
|
||||
Check-Tools -VMs $SampleVMs
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipeline=$True,
|
||||
Position=0)]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]
|
||||
$VMs
|
||||
)
|
||||
Process {
|
||||
#foreach ($VM in $VMs) {
|
||||
$OutofDate = $VMs | where {$_.ExtensionData.Guest.ToolsStatus -ne "toolsOk"}
|
||||
$Result = @($OutofDate | select Name,@{Name="ToolsVersion";Expression={$_.ExtensionData.Guest.Toolsversion}})
|
||||
|
||||
$Result
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
function Export-Tag {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(Mandatory = $True, Position = 1)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.VIServer]$Server,
|
||||
|
||||
[Parameter(Mandatory = $True, Position = 2)]
|
||||
[string]$Destination
|
||||
)
|
||||
|
||||
# Retrieve all categories
|
||||
$categoryList = Get-TagCategory -Server $server
|
||||
# Retrieve all tags
|
||||
$tagList = Get-Tag -Server $server
|
||||
# Store the tags and categories in a list to export them at once
|
||||
$export = @($categoryList, $tagList)
|
||||
# Export the tags and categories to the specified destination
|
||||
Export-Clixml -InputObject $export -Path $destination
|
||||
}
|
||||
|
||||
function Import-Tag {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(Mandatory = $True, Position = 1)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.VIServer]$Server,
|
||||
|
||||
[Parameter(Mandatory = $True, Position = 2)]
|
||||
[string]$Source
|
||||
)
|
||||
|
||||
# Import the tags and categories from the specified source
|
||||
$import = Import-Clixml -Path $source
|
||||
# Divide the input in separate lists for tags and categories
|
||||
$categoryList = $import[0]
|
||||
$tagList = $import[1]
|
||||
|
||||
# Store the newly created categories to avoid retrieving them later
|
||||
$categories = @()
|
||||
|
||||
# First create all categories on the server
|
||||
foreach ($category in $categoryList) {
|
||||
$categories += `
|
||||
New-TagCategory `
|
||||
-Name $category.Name `
|
||||
-Description $category.Description `
|
||||
-Cardinality $category.Cardinality `
|
||||
-EntityType $category.EntityType `
|
||||
-Server $server `
|
||||
| Out-Null
|
||||
}
|
||||
|
||||
# Then create all tags in the corresponding categories
|
||||
foreach ($tag in $tagList) {
|
||||
# Find the category object in the list
|
||||
$category = $categories | where {$_.Name -eq $tag.Category.Name}
|
||||
if ($category -eq $null) {$category = $tag.Category.Name}
|
||||
|
||||
New-Tag `
|
||||
-Name $tag.Name `
|
||||
-Description $tag.Description `
|
||||
-Category $category `
|
||||
-Server $server `
|
||||
| Out-Null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
function Get-BiosBootStatus {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Graf
|
||||
Organization: VMware
|
||||
Official Blog: blogs.vmware.com/PowerCLI
|
||||
Personal Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This will return the boot status of Virtual Machines, whether they
|
||||
are booting to the Guest OS or being forced to boot into BIOS.
|
||||
.Example
|
||||
# Returns all VMs and where they are booting
|
||||
Get-BiosBootStatus -VMs (Get-VM)
|
||||
.Example
|
||||
# Only returns VMs that are booting to BIOS
|
||||
Get-BiosBootStatus (Get-VM) -IsSetup
|
||||
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipeline=$True,
|
||||
Position=0)]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]
|
||||
$VM,
|
||||
[switch]$IsSetup
|
||||
)
|
||||
Process {
|
||||
if($IsSetup)
|
||||
{
|
||||
$Execute = $VM | where {$_.ExtensionData.Config.BootOptions.EnterBiosSetup -eq "true"} | Select Name,@{Name="EnterBiosSetup";Expression={$_.ExtensionData.config.BootOptions.EnterBiosSetup}}
|
||||
}
|
||||
else
|
||||
{
|
||||
$Execute = $VM | Select Name,@{Name="EnterBiosSetup";Expression={$_.ExtensionData.config.BootOptions.EnterBiosSetup}}
|
||||
}
|
||||
}
|
||||
End {$Execute}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,108 @@
|
||||
function install-HostClient {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 8/13/2015 9:12 AM
|
||||
Created by: Brian Graf
|
||||
Github: http://www.github.com/vtagion
|
||||
Twitter: @vBrianGraf
|
||||
Website: http://www.vtagion.com
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This advanced function will allow you to install the ESXi Host Client
|
||||
On all the hosts in a specified cluster.
|
||||
.Example
|
||||
Install-HostClient -Cluster (Get-Cluster Management-CL) -Datastore (Get-Datastore NFS-SAS-300GB-A) -vibfullpath c:\temp\esxui-2976804.vib
|
||||
|
||||
.Example
|
||||
$ds = Get-Datastore Main-shared
|
||||
$Cluster = Main-CL
|
||||
Install-HostClient -Cluster $cluster -Datastore $ds -vibfullpath c:\temp\esxui-2976804.vib
|
||||
|
||||
.Notes
|
||||
You must use shared storage for this to work correctly, otherwise only a single host will be able to install the vib and all others will fail
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true,HelpMessage="Must be shared storage across all hosts")]
|
||||
[ValidateScript({Get-Datastore $_})]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.NasDatastoreImpl]$Datastore,
|
||||
|
||||
[Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true,HelpMessage="Please specify a Cluster object")]
|
||||
[ValidateScript({Get-Cluster $_})]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.ComputeResourceImpl]$Cluster,
|
||||
|
||||
[Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true,HelpMessage="Specify the full path of the ESXi Host Client Vib")]
|
||||
[ValidateScript({Get-Item $_})]
|
||||
[String]$vibfullpath
|
||||
)
|
||||
Begin {
|
||||
|
||||
$VIBFile = Get-item $vibfullpath -ErrorAction SilentlyContinue
|
||||
|
||||
# Verify that VIB location is correct
|
||||
if ($VIBFile -eq $null){Throw "oops! looks like $VIBFile doesn't exist in this location."}
|
||||
|
||||
# Save filename to variable
|
||||
$VIBFilename = $vibfile.PSChildname
|
||||
|
||||
# Save datacenter to variable for Datastore path
|
||||
$dc = $Cluster | Get-Datacenter
|
||||
|
||||
#Get-Datastore -Name $Datastore
|
||||
|
||||
# Create Datastore Path string
|
||||
$Datastorepath = "vmstore:\" + $dc + "\" + $Datastore.Name + "\"
|
||||
|
||||
# Verbose info for debugging
|
||||
Write-verbose "DatastorePath = $Datastorepath"
|
||||
Write-verbose "Vibfile = $vibfile"
|
||||
Write-verbose "Vibfullpath = $vibfullpath"
|
||||
Write-verbose "VibFilename = $VIBFilename"
|
||||
|
||||
# check to see if file already exists or not before copying
|
||||
if (!(Test-Path -Path $Datastorepath)) {
|
||||
Copy-DatastoreItem $vibfile $Datastorepath -Force
|
||||
}
|
||||
|
||||
# validate the copy worked. If not, stop script
|
||||
if (!(Test-Path -Path $Datastorepath)) {
|
||||
Throw "Looks like the VIB did not copy to $Datastorepath. Check the filename and datastore path again and rerun this function."
|
||||
}
|
||||
|
||||
# Create VIB path string for ESXCLI
|
||||
$VIBPATH = "/vmfs/volumes/" + $datastore.name + "/" + "$VIBFilename"
|
||||
|
||||
}
|
||||
|
||||
Process {
|
||||
|
||||
|
||||
#$VIBPATH = "/vmfs/volumes/NFS-SAS-300GB-A/esxui-2976804.vib"
|
||||
|
||||
# Get each host in specified cluster that meets criteria
|
||||
Get-VMhost -Location $Cluster | where { $_.PowerState -eq "PoweredOn" -and $_.ConnectionState -eq "Connected" } | foreach {
|
||||
|
||||
Write-host "Preparing $($_.Name) for ESXCLI" -ForegroundColor Yellow
|
||||
|
||||
# Create ESXCLI variable for host for actions
|
||||
$ESXCLI = Get-EsxCli -VMHost $_
|
||||
|
||||
# Check to see if ESX-UI is already installed
|
||||
if (($ESXCLI.software.vib.list() | Select AcceptanceLevel,ID,InstallDate,Name,ReleaseDate,Status,Vendor,Version | Where {$_.Name -match "esx-ui"})) {Write-host "It appears ESX-UI is already installed on $_. Skipping..." -ForegroundColor Yellow} else {
|
||||
|
||||
Write-host "Installing ESXi Embedded Host Client on $($_.Name)" -ForegroundColor Yellow
|
||||
|
||||
# Saving command to variable to use for verification after command is run
|
||||
$action = $ESXCLI.software.vib.install($null,$null,$null,$null,$null,$null,$null,$null,$VIBPATH)
|
||||
|
||||
# Verify VIB installed successfully
|
||||
if ($action.Message -eq "Operation finished successfully."){Write-host "Action Completed successfully on $($_.Name)" -ForegroundColor Green} else {Write-host $action.Message -ForegroundColor Red}
|
||||
}
|
||||
}
|
||||
}
|
||||
End {
|
||||
Write-host "Function Complete" -ForegroundColor Green
|
||||
Write-Host "You may access your hosts at https://<host ipaddress>/ui" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
function Invoke-BiosBoot {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Graf
|
||||
Organization: VMware
|
||||
Official Blog: blogs.vmware.com/PowerCLI
|
||||
Personal Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function allows you to set a VM to boot into BIOS or Guest OS
|
||||
.Example
|
||||
# Set a VM to boot to BIOS
|
||||
Invoke-BiosBoot -VMs (Get-VM) -Bios
|
||||
.Example
|
||||
Invoke-BiosBoot -VMs (Get-VM) -OS
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipeline=$True,
|
||||
Position=0)]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]
|
||||
$VM,
|
||||
[switch]$Bios,
|
||||
[switch]$OS
|
||||
)
|
||||
Process {
|
||||
if($Bios)
|
||||
{
|
||||
Foreach ($VirtualMachine in $VM) {
|
||||
$object = New-Object VMware.Vim.VirtualMachineConfigSpec
|
||||
$object.bootOptions = New-Object VMware.Vim.VirtualMachineBootOptions
|
||||
$object.bootOptions.enterBIOSSetup = $true
|
||||
|
||||
$Reconfigure = $VirtualMachine | Get-View
|
||||
$Reconfigure.ReconfigVM_Task($object)
|
||||
$Return
|
||||
}
|
||||
}
|
||||
if($OS)
|
||||
{
|
||||
Foreach ($VirtualMachine in $VM) {
|
||||
$object = New-Object VMware.Vim.VirtualMachineConfigSpec
|
||||
$object.bootOptions = New-Object VMware.Vim.VirtualMachineBootOptions
|
||||
$object.bootOptions.enterBIOSSetup = $false
|
||||
|
||||
$Reconfigure = $VirtualMachine | Get-View
|
||||
$Reconfigure.ReconfigVM_Task($object)
|
||||
$Return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
function Remove-HostClient {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 8/13/2015 9:12 AM
|
||||
Created by: Brian Graf
|
||||
Github: http://www.github.com/vtagion
|
||||
Twitter: @vBrianGraf
|
||||
Website: http://www.vtagion.com
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This advanced function will allow you to remove the ESXi Host Client
|
||||
on all the hosts in a specified cluster.
|
||||
.Example
|
||||
Remove-HostClient -Cluster (Get-Cluster Management-CL)
|
||||
|
||||
.Example
|
||||
$Cluster = Main-CL
|
||||
Remove-HostClient -Cluster $cluster
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateScript({Get-Cluster $_})]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.ComputeResourceImpl]$Cluster
|
||||
)
|
||||
Process {
|
||||
|
||||
# Get all ESX hosts in cluster that meet criteria
|
||||
Get-VMhost -Location $Cluster | where { $_.PowerState -eq "PoweredOn" -and $_.ConnectionState -eq "Connected" } | foreach {
|
||||
|
||||
Write-host "Preparing to remove Host Client from $($_.Name)" -ForegroundColor Yellow
|
||||
|
||||
# Prepare ESXCLI variable
|
||||
$ESXCLI = Get-EsxCli -VMHost $_
|
||||
|
||||
# Check to see if VIB is installed on the host
|
||||
if (($ESXCLI.software.vib.list() | Where {$_.Name -match "esx-ui"})) {
|
||||
|
||||
Write-host "Removing ESXi Embedded Host Client on $($_.Name)" -ForegroundColor Yellow
|
||||
|
||||
# Command saved to variable for future verification
|
||||
$action = $esxcli.software.vib.remove($null,$null,$null,$null,"esx-ui")
|
||||
|
||||
# Verify VIB removed successfully
|
||||
if ($action.Message -eq "Operation finished successfully."){Write-host "Action Completed successfully on $($_.Name)" -ForegroundColor Green} else {Write-host $action.Message -ForegroundColor Red}
|
||||
|
||||
} else { Write-host "It appears Host Client is not installed on this host. Skipping..." -ForegroundColor Yellow }
|
||||
}
|
||||
}
|
||||
End {Write-host "Function complete" -ForegroundColor Green}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
Function Remove-IPPool {
|
||||
<#
|
||||
.Synopsis
|
||||
This function will remove IP-Pools from vCenter
|
||||
.Description
|
||||
This function will remove IP-Pools from vCenter based on the inputs provided
|
||||
.Example
|
||||
Assuming my datacenter was 'westwing' and my IPPool was 'IPPool1'
|
||||
remove-ippool westwing IPPool1
|
||||
.Notes
|
||||
Author: Brian Graf
|
||||
Role: Technical Marketing Engineer, VMware
|
||||
Last Edited: 05/01/2014
|
||||
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
Param (
|
||||
[Parameter(ValueFromPipeline = $true, valuefrompipelinebypropertyname = $true)]
|
||||
[String]$Datacenter,
|
||||
[Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
|
||||
[String]$PoolName
|
||||
)
|
||||
|
||||
Process {
|
||||
$dc = (Get-datacenter $Datacenter)
|
||||
$dcenter = New-Object VMware.Vim.ManagedObjectReference
|
||||
$dcenter.type = $dc.ExtensionData.moref.type
|
||||
$dcenter.Value = $dc.ExtensionData.moref.value
|
||||
|
||||
$IPPoolManager = Get-View -Id 'IpPoolManager'
|
||||
$SelectedPool = ($IPPoolManager.QueryIpPools($dc.ID) | Where-Object { $_.Name -like $PoolName })
|
||||
|
||||
$IPPool = Get-View -Id 'IpPoolManager-IpPoolManager'
|
||||
$IPPool.DestroyIpPool($dcenter, $SelectedPool.id, $true)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
function Set-LockdownLevel {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Set the Lockdown Level of ESX Hosts if PowerCLI connected to vCenter Server
|
||||
.PARAMETER VMHost
|
||||
The target ESX host
|
||||
.PARAMETER Disabled
|
||||
Sets the Lockdown level to Disabled
|
||||
.PARAMETER Normal
|
||||
Sets the Lockdown level to Normal
|
||||
.PARAMETER Strict
|
||||
Sets the Lockdown level to Strict
|
||||
.PARAMETER SuppressWarning
|
||||
Removes the messagebox popup verifying you want to proceed
|
||||
.EXAMPLE
|
||||
Set the Lockdown level to Normal on Host 10.144.99.231
|
||||
Set-LockdownLevel -VMhost 10.144.99.231 -Normal
|
||||
.EXAMPLE
|
||||
Set all ESX hosts Lockdown level to Disabled
|
||||
Get-VMhost | foreach { Set-LockdownLevel $_ -Disabled }
|
||||
.EXAMPLE
|
||||
Sets all ESX hosts Lockdown level to Normal and saves data to CSV, Suppresses warning
|
||||
Get-VMhost | foreach { Set-LockdownLevel $_ -filepath c:\temp\lockdowndata.csv -Disabled -SuppressWarning }
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 3/13/2015 5:55 AM
|
||||
Created by: Brian Graf
|
||||
Twitter: @vBrianGraf
|
||||
Email: grafb@vmware.com
|
||||
THIS SCRIPT IS NOT OFFICIALLY SUPPORTED BY VMWARE. USE AT YOUR OWN RISK
|
||||
===========================================================================
|
||||
#>
|
||||
|
||||
[CmdletBinding(DefaultParametersetName="Disabled")]
|
||||
Param(
|
||||
[Parameter(Mandatory=$True,Position=1,ValueFromPipeline=$True)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$VMhost,
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[string]$filePath,
|
||||
|
||||
[Parameter(ParameterSetName='Disabled')]
|
||||
[switch]$Disabled,
|
||||
|
||||
[Parameter(ParameterSetName='Normal')]
|
||||
[switch]$Normal,
|
||||
|
||||
[Parameter(ParameterSetName='Strict')]
|
||||
[switch]$Strict,
|
||||
|
||||
[switch]$SuppressWarning
|
||||
)
|
||||
|
||||
Process {
|
||||
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
|
||||
$Actions = @()
|
||||
|
||||
#Create an object to store changes and information in
|
||||
$Historical = New-Object -TypeName PSObject
|
||||
|
||||
#Specify the Three parameters to be used
|
||||
switch ($PsCmdlet.ParameterSetName) {
|
||||
"Disabled" {$level = "lockdownDisabled"}
|
||||
"Normal" {$level = "lockdownNormal"}
|
||||
"Strict" {$level = "lockdownStrict"}
|
||||
}
|
||||
Write-Host "you are changing the lockdown mode on host [$VMHost] to $level" -ForegroundColor Yellow
|
||||
if ((!($SuppressWarning)) -and ($level -ne "lockdownDisabled")) {
|
||||
|
||||
$OUTPUT = [System.Windows.Forms.MessageBox]::Show("By changing the Lockdown Mode level you may be locking yourself out of your host. If you understand the risks and would like to continue, click YES. If you wish to Cancel, click NO." , "CAUTION" , 4)
|
||||
|
||||
if ($OUTPUT -eq "NO" )
|
||||
{
|
||||
|
||||
Throw "User Aborted Lockdown Mode Level Change"
|
||||
|
||||
}
|
||||
}
|
||||
#If a Filepath was given, echo that it will save the info to CSV
|
||||
if ($Filepath) {
|
||||
Write-Host "Saving current Lockdown Mode level to CSV" -ForegroundColor Yellow}
|
||||
|
||||
#Retrieve the VMhost as a view object
|
||||
$lockdown = Get-View (Get-View -ViewType HostSystem -Filter @{"Name"="$VMHost"}).ConfigManager.HostAccessManager
|
||||
|
||||
#Add info to our object
|
||||
$Historical | Add-Member -MemberType NoteProperty -Name Timestamp -Value (Get-Date -Format g)
|
||||
$Historical | Add-Member -MemberType NoteProperty -Name Host -Value $VMhost
|
||||
$Historical | Add-Member -MemberType NoteProperty -Name OriginalValue -Value $lockdown.LockdownMode
|
||||
|
||||
#Perform Lockdown Mode change
|
||||
$lockdown.ChangeLockdownMode($level)
|
||||
|
||||
#Refresh View data
|
||||
$lockdown.UpdateViewData()
|
||||
|
||||
#Verify change happened
|
||||
if ($lockdown.LockdownMode -eq $level) {
|
||||
Write-Host "Lockdown Mode Level Updated Successfully on host [$VMHost]" -ForegroundColor Green} else {Write-Host "Uh Oh... Looks like the Lockdown Mode Level did not update for host [$VMHost]" -ForegroundColor Red}
|
||||
$Historical | Add-Member -MemberType NoteProperty -Name NewValue -Value $lockdown.LockdownMode
|
||||
$Actions += $Historical
|
||||
|
||||
#Export to CSV if filepath was given
|
||||
if ($filePath) {$Actions | Export-Csv "$filePath" -NoTypeInformation -NoClobber -Append}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,220 @@
|
||||
function Get-VMCPSettings {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 10/27/2015 9:25 PM
|
||||
Created by: Brian Graf
|
||||
Twitter: @vBrianGraf
|
||||
VMware Blog: blogs.vmware.com/powercli
|
||||
Personal Blog: www.vtagion.com
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function will allow users to view the VMCP settings for their clusters
|
||||
|
||||
.Example
|
||||
# This will show you the VMCP settings of your cluster
|
||||
Get-VMCPSettings -cluster LAB-CL
|
||||
|
||||
.Example
|
||||
# This will show you the VMCP settings of your cluster
|
||||
Get-VMCPSettings -cluster (Get-Cluster Lab-CL)
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$True,
|
||||
ValueFromPipelineByPropertyName=$True,
|
||||
HelpMessage='What is the Cluster Name?')]
|
||||
$cluster
|
||||
)
|
||||
Begin {
|
||||
# Determine input and convert to ClusterImpl object
|
||||
Switch ($cluster.GetType().Name)
|
||||
{
|
||||
"string" {$CL = Get-Cluster $cluster}
|
||||
"ClusterImpl" {$CL = $cluster}
|
||||
}
|
||||
}
|
||||
Process {
|
||||
# Work with the Cluster View
|
||||
$ClusterMod = Get-View -Id "ClusterComputeResource-$($cl.ExtensionData.MoRef.Value)"
|
||||
|
||||
# Create Hashtable with desired properties to return
|
||||
$properties = [ordered]@{
|
||||
'Cluster' = $ClusterMod.Name;
|
||||
'VMCP Status' = $clustermod.Configuration.DasConfig.VmComponentProtecting;
|
||||
'Protection For APD' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForAPD;
|
||||
'APD Timeout Enabled' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.EnableAPDTimeoutForHosts;
|
||||
'APD Timeout (Seconds)' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmTerminateDelayForAPDSec;
|
||||
'Reaction on APD Cleared' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmReactionOnAPDCleared;
|
||||
'Protection For PDL' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForPDL
|
||||
}
|
||||
|
||||
# Create PSObject with the Hashtable
|
||||
$object = New-Object -TypeName PSObject -Prop $properties
|
||||
|
||||
# Show object
|
||||
return $object
|
||||
}
|
||||
End {}
|
||||
|
||||
}
|
||||
|
||||
function Set-VMCPSettings {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 10/27/2015 9:25 PM
|
||||
Created by: Brian Graf
|
||||
Twitter: @vBrianGraf
|
||||
VMware Blog: blogs.vmware.com/powercli
|
||||
Personal Blog: www.vtagion.com
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function will allow users to enable/disable VMCP and also allow
|
||||
them to configure the additional VMCP settings
|
||||
For each parameter, users should use the 'Tab' button to auto-fill the
|
||||
possible values.
|
||||
|
||||
.Example
|
||||
# This will enable VMCP and configure the Settings
|
||||
Set-VMCPSettings -cluster LAB-CL -enableVMCP:$True -VmStorageProtectionForPDL `
|
||||
restartAggressive -VmStorageProtectionForAPD restartAggressive `
|
||||
-VmTerminateDelayForAPDSec 2000 -VmReactionOnAPDCleared reset
|
||||
|
||||
.Example
|
||||
# This will disable VMCP and configure the Settings
|
||||
Set-VMCPSettings -cluster LAB-CL -enableVMCP:$False -VmStorageProtectionForPDL `
|
||||
disabled -VmStorageProtectionForAPD disabled `
|
||||
-VmTerminateDelayForAPDSec 600 -VmReactionOnAPDCleared none
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$True,
|
||||
ValueFromPipelineByPropertyName=$True,
|
||||
HelpMessage='What is the Cluster Name?')]
|
||||
$cluster,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='True=Enabled False=Disabled')]
|
||||
[switch]$enableVMCP,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Actions that can be taken in response to a PDL event')]
|
||||
[ValidateSet("disabled","warning","restartAggressive")]
|
||||
[string]$VmStorageProtectionForPDL,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Options available for an APD response')]
|
||||
[ValidateSet("disabled","restartConservative","restartAggressive","warning")]
|
||||
[string]$VmStorageProtectionForAPD,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Value in seconds')]
|
||||
[Int]$VmTerminateDelayForAPDSec,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='This setting will instruct vSphere HA to take a certain action if an APD event is cleared')]
|
||||
[ValidateSet("reset","none")]
|
||||
[string]$VmReactionOnAPDCleared
|
||||
|
||||
)
|
||||
Begin{
|
||||
|
||||
# Determine input and convert to ClusterImpl object
|
||||
Switch ($cluster.GetType().Name)
|
||||
{
|
||||
"string" {$CL = Get-Cluster $cluster}
|
||||
"ClusterImpl" {$CL = $cluster}
|
||||
}
|
||||
}
|
||||
Process{
|
||||
# Create the object we will configure
|
||||
$settings = New-Object VMware.Vim.ClusterConfigSpecEx
|
||||
$settings.dasConfig = New-Object VMware.Vim.ClusterDasConfigInfo
|
||||
|
||||
# Based on $enableVMCP switch
|
||||
if ($enableVMCP -eq $false) {
|
||||
$settings.dasConfig.vmComponentProtecting = "disabled"
|
||||
}
|
||||
elseif ($enableVMCP -eq $true) {
|
||||
$settings.dasConfig.vmComponentProtecting = "enabled"
|
||||
}
|
||||
|
||||
#Create the VMCP object to work with
|
||||
$settings.dasConfig.defaultVmSettings = New-Object VMware.Vim.ClusterDasVmSettings
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings = New-Object VMware.Vim.ClusterVmComponentProtectionSettings
|
||||
|
||||
#Storage Protection For PDL
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForPDL = "$VmStorageProtectionForPDL"
|
||||
|
||||
#Storage Protection for APD
|
||||
switch ($VmStorageProtectionForAPD) {
|
||||
"disabled" {
|
||||
# If Disabled, there is no need to set the Timeout Value
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'disabled'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $false
|
||||
}
|
||||
|
||||
"restartConservative" {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'restartConservative'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $true
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmTerminateDelayForAPDSec = $VmTerminateDelayForAPDSec
|
||||
}
|
||||
|
||||
"restartAggressive" {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'restartAggressive'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $true
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmTerminateDelayForAPDSec = $VmTerminateDelayForAPDSec
|
||||
}
|
||||
|
||||
"warning" {
|
||||
# If Warning, there is no need to set the Timeout Value
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'warning'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Reaction On APD Cleared
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmReactionOnAPDCleared = "$VmReactionOnAPDCleared"
|
||||
|
||||
# Execute API Call
|
||||
$modify = $true
|
||||
$ClusterMod = Get-View -Id "ClusterComputeResource-$($cl.ExtensionData.MoRef.Value)"
|
||||
$ClusterMod.ReconfigureComputeResource_Task($settings, $modify) | out-null
|
||||
|
||||
|
||||
|
||||
}
|
||||
End{
|
||||
# Update variable data after API call
|
||||
$ClusterMod.updateViewData()
|
||||
|
||||
# Create Hashtable with desired properties to return
|
||||
$properties = [ordered]@{
|
||||
'Cluster' = $ClusterMod.Name;
|
||||
'VMCP Status' = $clustermod.Configuration.DasConfig.VmComponentProtecting;
|
||||
'Protection For APD' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForAPD;
|
||||
'APD Timeout Enabled' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.EnableAPDTimeoutForHosts;
|
||||
'APD Timeout (Seconds)' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmTerminateDelayForAPDSec;
|
||||
'Reaction on APD Cleared' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmReactionOnAPDCleared;
|
||||
'Protection For PDL' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForPDL
|
||||
}
|
||||
|
||||
# Create PSObject with the Hashtable
|
||||
$object = New-Object -TypeName PSObject -Prop $properties
|
||||
|
||||
# Show object
|
||||
return $object
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 5/27/2015 3:24 PM
|
||||
Created by: Brian Graf
|
||||
Twitter: @vBrianGraf
|
||||
Blog: http://www.vtagion.com
|
||||
===========================================================================
|
||||
#>
|
||||
|
||||
#Encoded Hardening Guide
|
||||
$Global:Base64 = "UEsDBBQABgAIAAAAIQByzFKQpAEAANcGAAATAAgCW0NvbnRlbnRfVHlwZXNdLnhtbCCiBAIooAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACslctOwzAQRfdI/EPkLUpcWCCEmnbBYwlIlA8w9qSx6he2C+3fM3bpg6o0Qs0mTmLPvWec8WQ4XmhVfIIP0pqaXFYDUoDhVkgzrcnb5LG8IUWIzAimrIGaLCGQ8ej8bDhZOggFRptQkzZGd0tp4C1oFirrwOBMY71mER/9lDrGZ2wK9GowuKbcmggmljFpkNHwHho2V7F4WODrFcmXbkhxt1qXrGoidYpflGmGHozxoMJeEHNOSc4iZkc/jdgjK3+oKozMa0IrXbhA9D8c0sxvql2Dn7hn3E4vBRQvzMcnppGdLhT9sn72bu2sOi5ygNI2jeQgLJ9r3LUqOA9MhBYgalXlsdJMmjX3Ef+8ONA8XPYMkvLLwh0cEWsEaL6ejpBlOgyx2gzwVAKh55R3lDsYQlwq6Nt+Jdrl3DIP4jV6PNG9A+xqd3129o47QGMa+i69LNrh/zEHv5ysILb3fZNslbuKkil+1+Kp7bsk17rH/LGVvHjrAjZiD/8HWHfNFF06FAIfJWz65qH+s3HEfnlyxpB+EwLEAW+af0ujbwAAAP//AwBQSwMEFAAGAAgAAAAhAOT5JVMGAQAA3AIAAAsACAJfcmVscy8ucmVscyCiBAIooAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACs0t1qwyAUB/D7wd5Bzn1j2o0xRpPejEHvxsge4FRPEkn0iNo1ffvJYB+BrgzWS/X496fH9Wayo3ijEA27CpZFCYKcYm1cV8Fr87S4BxETOo0jO6rgSBE29fXV+oVGTHlT7I2PIqe4WEGfkn+QMqqeLMaCPbm80nKwmPIwdNKjGrAjuSrLOxl+ZkA9yxRbXUHY6hsQzdHnk/+TLS0l1JhQKg608CHLQjL5LqLB0FGqQLN6ztPxo6LIapCnQavLglK/tzuHZjxB+VorDrb9zbP8u4fb1ih6ZLW35NKJHsh5xTdpGuWBw7BjHs69ze0lLTQlcpr0+Xah958iOfuT9TsAAAD//wMAUEsDBBQABgAIAAAAIQBQ+Z9uEwEAAMgDAAAaAAgBeGwvX3JlbHMvd29ya2Jvb2sueG1sLnJlbHMgogQBKKAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsk8tqwzAQRfeF/oOYfS07bUMpkbNoKWTbph8g5LFlYo+MRn347ysMiW0I7sYbwdxBdw7z2O1/20Z8o+fakYIsSUEgGVfUVCn4PL7dPYHgoKnQjSNU0CPDPr+92b1jo0P8xLbuWEQXYgU2hO5ZSjYWW82J65BipnS+1SGGvpKdNiddodyk6Vb6qQfkM09xKBT4Q3EP4th3sfL/3q4sa4Ovzny1SOFKCWkcEZoBO9pqX2FQMBGTSAvyOshmTZAQG4QjwhDK4c2WGLI1GX6cP7FFDCPHRWI5ZBZhtqtORjfmxeqaJnM5S0sdeVwTgq32WHwEH7efR5CZvATzsCpM6Jt4bJc15SE+l5ez+8v/AAAA//8DAFBLAwQUAAYACAAAACEAH5G1vY0CAAAtBQAADwAAAHhsL3dvcmtib29rLnhtbKyU32/TMBDH35H4H4zV1zY/1q5dlGRa18ImIZi2sb1UQm58baw6drCdtRPif+ecrNCxlyF4ic928rm7790lPd1VkjyAsUKrjEaDkBJQheZCrTP65fZ9f0KJdUxxJrWCjD6Cpaf52zfpVpvNUusNQYCyGS2dq5MgsEUJFbMDXYPCm5U2FXO4NevA1gYYtyWAq2QQh+FxUDGhaEdIzGsYerUSBcx00VSgXAcxIJnD8G0parunVcVrcBUzm6buF7qqEbEUUrjHFkpJVSSXa6UNW0pMexeN9mQ0X6ArURht9coNEBV0Qb7INwqDKOpSztOVkHDXyU5YXX9ilfciKZHMujkXDnhGj3Grt/DswDT1tBESb6PhMA5pkP8qxZUhHFaske4Wi7DH44ujoziO/ZuY1Jl0YBRzcK6VQw2f1P9XvVr2eamxOuQavjXCADaFly1P8cmKhC3tFXMlaYzM6GLxUG2ZgX6prVvclGhy8l5LjpIsPiuYGfEA08YKBdYuLpjhoLAlyYdGcLCL40G4OKgHe1nsv6gIK7w0AWrTxd/Zf+qUp77b7wRs7W/F/Zbs7oXieptRnJ3HA3vbHt8L7sqMxtFkjPfd2QWIdekyOhmjPt73AbqdD3TRrkS1fXHjZybCQfTrpS89JSYRaJhLHrWE/WfYAKgZ9/2EkIPdE2q+a8svZ8yxr4iRumCy5XsuRlgKjlp7F3nn9l3vrBclvfveOEqDAyCG/dwZggpsQb+0MY7iUdQGBzv30bo8xRWrLzL6PRqGZ+PwZNgP50ej/nByEvcnw6O4fz6cxfPReD6bT0c//u/AYRMm+3+WjxJbzt0aVmywra5hNWUWB7DTEuPE5PZRB/uv8p8AAAD//wMAUEsDBBQABgAIAAAAIQCpTAfKqgMAAJQUAAANAAAAeGwvc3R5bGVzLnhtbOxYbW/bNhD+PmD/gdB3RS+xPNuQ1NVxBBTIumHxgH2lJcrmwheBpFO7w/777iTZVtpsbZMMyNp8kcgj+fDu9NxRvPTVTgpyy4zlWmVedBZ6hKlSV1ytM++3ZeFPPGIdVRUVWrHM2zPrvcq//y61bi/Y9YYxRwBC2czbONfMgsCWGyapPdMNUzBSayOpg65ZB7YxjFYWF0kRxGE4DiTlyusQZrL8HBBJzc228UstG+r4igvu9i2WR2Q5e7NW2tCVAFV30YiWB+y28xG85KXRVtfuDOACXde8ZB9rOQ2mASDlaa2Vs6TUW+UyLwZo3GF2o/Q7VeAQOLCflaf2PbmlAiSRF+RpqYU2xIFnQLFWoqhk3YwLKvjKcJxWU8nFvhPHKGid2c+THExDYYB6dNo8cJ8eoX1ZQOJCDOzqBHkK/nXMqAJGSd9e7hswQAEVOkVg6JOz14buozgZLAjaDfN0pU0F1Dt4FJ3XifJUsNqBqYavN/h2uoHnSjsH3ylPK07XWlGBzjis6BtgTsmEuEZ6/l7fwd7VRG1lId2bKvOA6OjGQxMM6ZsdXtdB/CFahz2AHYPKXw5LdvUR/xGrCW0asX8t+FpJhpREBwKZui55Z2izZLtWjobs6n/WNQJv3O+Co67dbshz3Oixe+OGn3T/B3u/3coVM0WbUPoouuO90fQJQO8xDJz39PscqAVkGjD2Dl+PzCOYLDLvLVouIO307CGrLReOq3u4CpjV7sT+OAZmgGBIj402/D18AkxSa6aYQWg4CRwvUdTFmkccMLine truncated
|
||||
|
||||
Function Import-Xls {
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Import an Excel file.
|
||||
|
||||
.DESCRIPTION
|
||||
Import an excel file. Since Excel files can have multiple worksheets, you can specify the worksheet you want to import. You can specify it by number (1, 2, 3) or by name (Sheet1, Sheet2, Sheet3). Imports Worksheet 1 by default.
|
||||
|
||||
.PARAMETER Path
|
||||
Specifies the path to the Excel file to import. You can also pipe a path to Import-Xls.
|
||||
|
||||
.PARAMETER Worksheet
|
||||
Specifies the worksheet to import in the Excel file. You can specify it by name or by number. The default is 1.
|
||||
Note: Charts don't count as worksheets, so they don't affect the Worksheet numbers.
|
||||
|
||||
.INPUTS
|
||||
System.String
|
||||
|
||||
.OUTPUTS
|
||||
Object
|
||||
|
||||
.EXAMPLE
|
||||
".\employees.xlsx" | Import-Xls -Worksheet 1
|
||||
Import Worksheet 1 from employees.xlsx
|
||||
|
||||
.EXAMPLE
|
||||
".\employees.xlsx" | Import-Xls -Worksheet "Sheet2"
|
||||
Import Worksheet "Sheet2" from employees.xlsx
|
||||
|
||||
.EXAMPLE
|
||||
".\deptA.xslx", ".\deptB.xlsx" | Import-Xls -Worksheet 3
|
||||
Import Worksheet 3 from deptA.xlsx and deptB.xlsx.
|
||||
Make sure that the worksheets have the same headers, or have some headers in common, or that it works the way you expect.
|
||||
|
||||
.EXAMPLE
|
||||
Get-ChildItem *.xlsx | Import-Xls -Worksheet "Employees"
|
||||
Import Worksheet "Employees" from all .xlsx files in the current directory.
|
||||
Make sure that the worksheets have the same headers, or have some headers in common, or that it works the way you expect.
|
||||
|
||||
.LINK
|
||||
Import-Xls
|
||||
http://gallery.technet.microsoft.com/scriptcenter/17bcabe7-322a-43d3-9a27-f3f96618c74b
|
||||
Export-Xls
|
||||
http://gallery.technet.microsoft.com/scriptcenter/d41565f1-37ef-43cb-9462-a08cd5a610e2
|
||||
Import-Csv
|
||||
Export-Csv
|
||||
|
||||
.NOTES
|
||||
Author: Francis de la Cerna
|
||||
Created: 2011-03-27
|
||||
Modified: 2011-04-09
|
||||
#Requires –Version 2.0
|
||||
|
||||
#>
|
||||
|
||||
[CmdletBinding(SupportsShouldProcess = $true)]
|
||||
Param (
|
||||
[parameter(
|
||||
mandatory = $true,
|
||||
position = 1,
|
||||
ValueFromPipeline = $true,
|
||||
ValueFromPipelineByPropertyName = $true)]
|
||||
[String[]]$Path,
|
||||
[parameter(mandatory = $false)]
|
||||
$Worksheet = 1,
|
||||
[parameter(mandatory = $false)]
|
||||
[switch]$Force
|
||||
)
|
||||
|
||||
Begin {
|
||||
function GetTempFileName($extension) {
|
||||
$temp = [io.path]::GetTempFileName();
|
||||
$params = @{
|
||||
Path = $temp;
|
||||
Destination = $temp + $extension;
|
||||
Confirm = $false;
|
||||
Verbose = $VerbosePreference;
|
||||
}
|
||||
Move-Item @params;
|
||||
$temp += $extension;
|
||||
return $temp;
|
||||
}
|
||||
|
||||
# since an extension like .xls can have multiple formats, this
|
||||
# will need to be changed
|
||||
#
|
||||
$xlFileFormats = @{
|
||||
# single worksheet formats
|
||||
'.csv' = 6; # 6, 22, 23, 24
|
||||
'.dbf' = 11; # 7, 8, 11
|
||||
'.dif' = 9; #
|
||||
'.prn' = 36; #
|
||||
'.slk' = 2; # 2, 10
|
||||
'.wk1' = 31; # 5, 30, 31
|
||||
'.wk3' = 32; # 15, 32
|
||||
'.wk4' = 38; #
|
||||
'.wks' = 4; #
|
||||
'.xlw' = 35; #
|
||||
|
||||
# multiple worksheet formats
|
||||
'.xls' = -4143; # -4143, 1, 16, 18, 29, 33, 39, 43
|
||||
'.xlsb' = 50; #
|
||||
'.xlsm' = 52; #
|
||||
'.xlsx' = 51; #
|
||||
'.xml' = 46; #
|
||||
'.ods' = 60; #
|
||||
}
|
||||
|
||||
$xl = New-Object -ComObject Excel.Application;
|
||||
$xl.DisplayAlerts = $false;
|
||||
$xl.Visible = $false;
|
||||
}
|
||||
|
||||
Process {
|
||||
$Path | ForEach-Object {
|
||||
|
||||
if ($Force -or $psCmdlet.ShouldProcess($_)) {
|
||||
|
||||
$fileExist = Test-Path $_
|
||||
|
||||
if (-not $fileExist) {
|
||||
Write-Error "Error: $_ does not exist" -Category ResourceUnavailable;
|
||||
} else {
|
||||
# create temporary .csv file from excel file and import .csv
|
||||
#
|
||||
$_ = (Resolve-Path $_).toString();
|
||||
$wb = $xl.Workbooks.Add($_);
|
||||
if ($?) {
|
||||
$csvTemp = GetTempFileName(".csv");
|
||||
$ws = $wb.Worksheets.Item($Worksheet);
|
||||
$ws.SaveAs($csvTemp, $xlFileFormats[".csv"]);
|
||||
$wb.Close($false);
|
||||
Remove-Variable -Name ('ws', 'wb') -Confirm:$false;
|
||||
Import-Csv $csvTemp;
|
||||
Remove-Item $csvTemp -Confirm:$false -Verbose:$VerbosePreference;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
End {
|
||||
$xl.Quit();
|
||||
Remove-Variable -name xl -Confirm:$false;
|
||||
[gc]::Collect();
|
||||
}
|
||||
}
|
||||
Function Show-HardeningGuide {
|
||||
$Global:XLS = Import-XLS $env:temp\HG.XLSX
|
||||
$ShowGuide = $XLS | Out-GridView
|
||||
}
|
||||
Function Assess-VM {
|
||||
<#
|
||||
.DESCRIPTION
|
||||
This cmdlet will allow you to assess the security of the VM's in your environment
|
||||
.EXAMPLE
|
||||
# Specify Virtual Machines to Assess
|
||||
$VM = Get-VM MGMT-AD, MGMT-VCO, WebCommander, Exchange01
|
||||
|
||||
# Assess against Risk Profile 2
|
||||
Assess-VM -VM $VM -RiskProfile 2
|
||||
|
||||
.EXAMPLE
|
||||
# Assess all VM's against specific ID's
|
||||
$VM = Get-VM
|
||||
Assess-VM -VM $VM -ID 9,10,12,22,33,49
|
||||
|
||||
.EXAMPLE
|
||||
# Assess All VM's against All ID's
|
||||
Assess-VM -VM (Get-VM)
|
||||
#>
|
||||
[CmdletBinding(
|
||||
DefaultParameterSetName = ”ID”
|
||||
)]
|
||||
Param (
|
||||
#Object receiving the hardening
|
||||
[Parameter(
|
||||
Position = 0,
|
||||
ValueFromPipeline = $true,
|
||||
ValueFromPipelineByPropertyName = $true,
|
||||
HelpMessage = 'What object are you running this against?')]
|
||||
#[string]$VMs,
|
||||
[PSObject[]]
|
||||
$VM,
|
||||
|
||||
#Hardening Guide Profile
|
||||
[Parameter(Mandatory = $false,
|
||||
ValueFromPipeline = $false,
|
||||
HelpMessage = "You must choose which Hardening Guide Risk Profile to use (1-3).",
|
||||
ParameterSetName = 'RiskProfile')]
|
||||
#[ValidateRange(1,3)]
|
||||
[int]$RiskProfile,
|
||||
|
||||
#Hardening Guide Guideline ID
|
||||
[Parameter(Mandatory = $false,
|
||||
ValueFromPipeline = $false,
|
||||
ParameterSetName = 'ID')]
|
||||
[string[]]$ID,
|
||||
|
||||
[parameter(ParameterSetName = "ID",
|
||||
ValueFromPipeline = $false)]
|
||||
$AllIDs = "1"
|
||||
)
|
||||
|
||||
BEGIN {
|
||||
# Validate VM Parameter
|
||||
# This ensures the object being passed is an object rather than a string
|
||||
[int]$Err = 0
|
||||
foreach ($object in $vm) { if (($object.GetType().FullName) -ne "VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl") { $Err += 1 } }
|
||||
if ($Err -gt 0) {
|
||||
Write-Error "One or more objects specified in the `$VM parameter is not a VM object"
|
||||
Break
|
||||
}
|
||||
|
||||
|
||||
# Get the Date, used for folder creation and report
|
||||
$Date = (Get-Date -Format MM.dd.yy)
|
||||
|
||||
# Create array of ID's
|
||||
if (-not $ID) {
|
||||
$IDs = $null
|
||||
} else {
|
||||
$IDs = $ID.Replace(' ', '').split(',')
|
||||
}
|
||||
|
||||
# Manage Risk Profile Parameter value
|
||||
$RiskArray = @("1","2","3")
|
||||
|
||||
|
||||
### HTML CSS CODE ###
|
||||
$head = @'
|
||||
<style>
|
||||
BODY{font-family:Arial; background-color:#494a4d;}
|
||||
TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse; width: 95.3%}
|
||||
TH{color:#006990; font-size:1.3em; border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color:#bdbdbd}
|
||||
TD{color:#006990; border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color:white}
|
||||
h1 {color: #FFFFFF;}
|
||||
h2 {BORDER-RIGHT: #bbbbbb 1px solid;PADDING-RIGHT: 0px;BORDER-TOP: #bbbbbb 1px solid;DISPLAY: block;PADDING-LEFT: 0px;FONT-WEIGHT: bold;FONT-SIZE: 16pt;MARGIN-BOTTOM: -1px;MARGIN-LEFT: AUTO;BORDER-LEFT: #bbbbbb 1px solid;COLOR: #FFFFFF;MARGIN-RIGHT: AUTO;PADDING-TOP: 4px;BORDER-BOTTOM: #bbbbbb 1px solid;FONT-FAMILY: Tahoma;POSITION: relative;HEIGHT: 1.5em;WIDTH: 95%;TEXT-INDENT: 10px;BACKGROUND-COLOR: #387C2C;}
|
||||
h3 {BORDER-RIGHT: #bbbbbb 1px solid;PADDING-RIGHT: 0px;BORDER-TOP: #bbbbbb 1px solid;DISPLAY: block;PADDING-LEFT: 0px;FONT-WEIGHT: bold;FONT-SIZE: 12pt;MARGIN-BOTTOM: -1px;MARGIN-TOP: -1px;MARGIN-LEFT: AUTO;BORDER-LEFT: #bbbbbb 1px solid;COLOR: #FFFFFF;MARGIN-RIGHT: AUTO;PADDING-TOP: 4px;BORDER-BOTTOM: #bbbbbb 1px solid;FONT-FAMILY: Tahoma;POSITION: relative;HEIGHT: 1.5em;WIDTH: 95%;TEXT-INDENT: 10px;BACKGROUND-COLOR: #6DB33F;}
|
||||
h4 {color: #00FFFF; margin-bottom: 0cm; margin-top: 0cm;}
|
||||
br { line-height: 25%;}
|
||||
</style>
|
||||
'@
|
||||
#####################
|
||||
|
||||
#C heck to see if HG exists in the $Env:Temp folder, if not, place it there
|
||||
if (!(Test-Path -Path "$env:Temp\HG.XLSX")) {
|
||||
|
||||
# Decode Hardening Guide from script
|
||||
$Content = [System.Convert]::FromBase64String($Global:Base64)
|
||||
Set-Content -Path $env:temp\HG.XLSX -Value $Content -Encoding Byte
|
||||
}
|
||||
|
||||
#Save Imported Hardening Guide to $XLS
|
||||
$Global:XLS = Import-XLS $env:temp\HG.XLSX
|
||||
|
||||
}
|
||||
|
||||
PROCESS {
|
||||
|
||||
# If risk profile is provided
|
||||
if ($RiskArray -contains $RiskProfile) {
|
||||
|
||||
$Guidelines = ($XLS | ?{ $_."Guideline ID" -like "VM*" -and $_."Risk Profile" -match $RiskProfile })
|
||||
foreach ($Guideline in $Guidelines) {
|
||||
|
||||
$ID = $Guideline.ID
|
||||
$GuidelineID = $Guideline."Guideline ID"
|
||||
$Name = ($GuidelineID.Split("."))[1]
|
||||
$Assessment = $Guideline."PowerCLI Command Assessment"
|
||||
$Assessment = $Assessment -replace "Get-VM", "`$VM"
|
||||
$Description = $Guideline."Description"
|
||||
|
||||
Write-Host "Processing: $ID - $Name" -ForegroundColor CYAN
|
||||
if ($assessment -ne "") {
|
||||
$run = iex ($Assessment)
|
||||
if ($run -eq $null) {
|
||||
$run = New-Object System.object
|
||||
$run | Add-Member -type NoteProperty -name Name -value "Clear"
|
||||
$run | Add-Member -type NoteProperty -name Description -value "NO SECURITY HARDENING NEEDED FOR THIS GUIDELINE"
|
||||
}
|
||||
$Task = $run | ConvertTo-Html -Fragment -PreContent "<Center><h2>$ID - $Name</h2><h3>$Description</h3></Center>" -PostContent "<br>" | Out-String
|
||||
$Tasks += $task
|
||||
}
|
||||
}
|
||||
} elseif ($AllIDs -eq "1" -and $ID -eq $null) {
|
||||
|
||||
$Guidelines = ($XLS | ?{ $_."Guideline ID" -like "VM*" })
|
||||
foreach ($Guideline in $Guidelines) {
|
||||
$ID = $Guideline.ID
|
||||
$GuidelineID = $Guideline."Guideline ID"
|
||||
$Name = ($GuidelineID.Split("."))[1]
|
||||
$Assessment = $Guideline."PowerCLI Command Assessment"
|
||||
$Assessment = $Assessment -replace "Get-VM", "`$VM"
|
||||
$Description = $Guideline."Description"
|
||||
Write-Host "Processing: $ID - $Name" -ForegroundColor CYAN
|
||||
if ($assessment -ne "") {
|
||||
$run = iex ($Assessment)
|
||||
if ($run -eq $null) {
|
||||
$run = New-Object System.object
|
||||
$run | Add-Member -type NoteProperty -name Name -value "Clear"
|
||||
$run | Add-Member -type NoteProperty -name Description -value "NO SECURITY HARDENING NEEDED FOR THIS GUIDELINE"
|
||||
}
|
||||
$Task = $run | ConvertTo-Html -Fragment -PreContent "<Center><h2>$ID - $Name</h2><br><h3>$Description</h3></Center>" | Out-String
|
||||
$Tasks += $task
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
# If Guideline IDs are provided
|
||||
foreach ($line in $ID) {
|
||||
$Guideline = ($XLS | ?{ $_."Guideline ID" -like "VM*" -and $_."ID" -eq $Line })
|
||||
$GuidelineID = $Guideline."Guideline ID"
|
||||
if ($GuidelineID -eq $null) {
|
||||
Write-Host "$line is an invalid ID for this object... moving to next ID" -ForegroundColor 'Red'
|
||||
Continue
|
||||
}
|
||||
$Name = ($GuidelineID.Split("."))[1]
|
||||
|
||||
$Description = $Guideline."Description"
|
||||
$Assessment = $Guideline."PowerCLI Command Assessment"
|
||||
$Assessment = $Assessment -replace "Get-VM", "`$VM"
|
||||
Write-Host "Processing: $line - $Name" -ForegroundColor CYAN
|
||||
if ($assessment -ne "") {
|
||||
$run = iex ($Assessment)
|
||||
if ($run -eq $null) {
|
||||
$run = New-Object System.object
|
||||
$run| Add-Member -type NoteProperty -name Name -value "Clear"
|
||||
$run | Add-Member -type NoteProperty -name Description -value "NO SECURITY HARDENING NEEDED FOR THIS GUIDELINE"
|
||||
}
|
||||
$Task = $run | ConvertTo-Html -Fragment -PreContent "<Center><h2>$line - $Name</h2><br><h3>$Description</h3></Center>" -PostContent "<br>" | Out-String
|
||||
$Tasks += $task
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END {
|
||||
# if no tasks were generated, end function and do NOT create empty report
|
||||
if ($tasks -eq $null) {Break }
|
||||
|
||||
# Get's end time Hours/Minutes for creating the HTML report
|
||||
$time = (get-date -Format HH-mm)
|
||||
|
||||
# Checks to see if a folder has been created for that date. If not, it will create one.
|
||||
if (!(Test-Path c:\Temp\$Date)) {
|
||||
Write-Host "Folder does not exist... Creating" -ForegroundColor 'Yellow'
|
||||
New-item "C:\Temp\$date" -type Directory
|
||||
}
|
||||
|
||||
# HTML Report is then generated
|
||||
$HTML = ConvertTo-HTML -head $head -PostContent "<Center>$Tasks</Center>" -PreContent “<Center><h1>vSphere 6 VM Hardening Report</h1></Center>” | Out-File "c:\Temp\$Date\$Time-VMAssessment.html" -Force
|
||||
|
||||
# Report is opened for user to see
|
||||
invoke-item "c:\Temp\$Date\$Time-VMAssessment.html"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user