Functions/Functions.ps1

Function Get-DRBackup {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 06122019
 
    .DESCRIPTION
    The purpose of this function is to provide records that would simplify bringing back up a large vcenter array in a recovery scenario.
 
    Get's Domain DNS Records, Hosts, and VM's, saves the Gatered data to 3 seperate spreadsheets, and prompts to Delete any files older than 45 days in the output path
 
    .EXAMPLE
    Specify the DNS Zone Name containg the VMware DNS Records.
    Specify a Domain Controller containing the Primary DNS Zone.
    Specify the folder where the records are to be saved.
    Specify the Vcenter Server hosting the VM's.
 
    Get-DRRecords -DNSZone DNSZone.com -PrimaryDNSServer DNSServer -OutPath c:\drbackup -Vcenter vcentername
 
    .NOTES
    Requires the VMware.PowerCLI Module
    #>


    [CmdletBinding(SupportsShouldProcess)]
    Param (
        [Parameter(Mandatory = $true)]$DNSZone,
        [Parameter(Mandatory = $true)]$PrimaryDNSServer,
        [Parameter(Mandatory = $true)]$OutPath,
        [Parameter(Mandatory = $true)]$VCenter
    )

    #Get's DNS Records

    #Variables for DNS Records
    $date = Get-Date -format m
    $datepathdns = "$OutPath\$date dns.csv"

    #Export Dns zone
    $results = Get-DnsServerResourceRecord -zonename $DNSZone -computername $PrimaryDNSServer | Select-Object hostname, Recordtype, timestamp, @{n = 'IP'; E = { $_.recorddata.IPV4Address } }
    $results | Export-Csv "$datepathdns" -NoTypeInformation

    #Variables for VMware Records
    $date = Get-Date -format m
    $datepathvms = "$OutPath\$date vms.csv"
    $datepathhost = "$OutPath\$date hosts.csv"

    #connect to old vcenter
    Connect-VIServer -Server $VCenter

    #Get's vm list
    Get-VM * | Select-Object name, vmhost, @{N = "IP Address"; E = { @($_.guest.IPAddress -join '|') } } | Export-Csv "$datepathvms" -NoTypeInformation

    #Get vmhosts
    Get-VMHost |
    Select-Object Name, @{n = "ManagementIP"; e = { Get-VMHostNetworkAdapter -VMHost $_ -VMKernel |
            Where-Object { $_.ManagementTrafficEnabled } |
            ForEach-Object { $_.Ip } }
    } |
    Export-Csv "$datepathhost" -NoTypeInformation

    #Confirm the Function was successful by viewing the files have size to them
    Set-Location $OutPath
    Get-ChildItem | Sort-Object name -descending | Format-Table

    #Delete backup files older than 45 days
    Write-Host "WARNING: " -Foregroundcolor Red -NoNewline
    Write-Host "This will delete all files in the output path including those not generated by this function" -ForegroundColor Yellow
    $Prompt = Read-Host "Do you wish to delete all files in path older than 45 days?"

    if ($Prompt -eq 'Yes') {
        cmd.exe /c forfiles /p "$OutPath" /d -7 /C "cmd /c del @path"
    }
    else {
        Write-Host "You selected No" -ForegroundColor Yellow
    }
}

Function Get-HostMemoryDimms {

    <#
    .SYNOPSIS
        Returns memory dimms configuration for esxi
 
    .DESCRIPTION
        This function utilizes wsman / cim in order to download configuration of memory dims in ESXi.
 
    .PARAMETER esxi
        Specify esxi host for which you want to get the report
 
    .PARAMETER rootpw
        Password for user root inside esxi
 
    .EXAMPLE
        PS C:\> Get-HostMemoryDimms -VMHost 'Esxi048.domain.local' -rootpw 'password.123' | ft *
        BankLabel Manufacturer Description SizeGB MemoryType MemoryDef
        --------- ------------ ----------- ------ ---------- ---------
        P0_Node0_Channel0_Dimm0 Samsung P1-DIMMA1 16 24 DDR3
        P0_Node0_Channel0_Dimm1 Samsung P1-DIMMA2 16 24 DDR3
        P0_Node0_Channel1_Dimm0 Samsung P1-DIMMB1 16 24 DDR3
        P0_Node0_Channel1_Dimm1 Samsung P1-DIMMB2 16 24 DDR3
        P0_Node0_Channel2_Dimm0 Samsung P1-DIMMC1 16 24 DDR3
        P1_Node1_Channel2_Dimm0 Samsung P2-DIMMG1 16 24 DDR3
        P1_Node1_Channel2_Dimm1 Samsung P2-DIMMG2 16 24 DDR3
        P1_Node1_Channel3_Dimm0 Samsung P2-DIMMH1 16 24 DDR3
        P1_Node1_Channel3_Dimm1 Samsung P2-DIMMH2 16 24 DDR3
                                Winbond ...625 11 Flash
    #>


    param(
        [Parameter(Mandatory = $true)][String]$VMHost,
        [Parameter(Mandatory = $true)][string]$rootpw
    )

    #MemoryTypes from: https://msdn.microsoft.com/en-us/library/aa394347(v=vs.85).aspx
    $MemHash = @{
        '0'  = 'Unknown';
        '1'  = 'Other';
        '2'  = 'DRAM';
        '3'  = 'Synchronous DRAM';
        '4'  = 'Cache DRAM';
        '5'  = 'EDO';
        '6'  = 'EDRAM';
        '7'  = 'VRAM';
        '8'  = 'SRAM';
        '9'  = 'RAM';
        '10' = 'ROM';
        '11' = 'Flash';
        '12' = 'EEPROM';
        '13' = 'FEPROM';
        '14' = 'EPROM';
        '15' = 'CDRAM';
        '16' = '3DRAM';
        '17' = 'SDRAM';
        '18' = 'SGRAM';
        '19' = 'RDRAM';
        '20' = 'DDR';
        '21' = 'DDR2';
        '22' = 'DDR2 FB-DIMM';
        '23' = 'DDR2 FB-DIMM';
        '24' = 'DDR3';
        '25' = 'FBD2'
    }


    $pass = ConvertTo-SecureString $rootpw -Force
    $cred = New-Object System.Management.Automation.PSCredential ('root', $pass)
    $CIMOpt = New-CimSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -Encoding Utf8 -UseSsl
    $Session = New-CimSession -Authentication Basic -Credential $cred -ComputerName $VMHost -port 443 -SessionOption $CIMOpt
    Get-CimInstance -CimSession $Session CIM_PhysicalMemory | Select-Object BankLabel, Manufacturer, Description , @{n = 'SizeGB'; e = { $_.Capacity / 1GB } }, MemoryType, @{n = 'MemoryDef'; e = { $MemHash[$_.MemoryType] } } | Format-Table

}

Function Get-HostSerialNumber {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 06122019
 
    .DESCRIPTION
    Get serial numbers for VM Hosts
 
    .EXAMPLE
    Get-HostSerialNumber
 
    .NOTES
    Requires the VMware.PowerCLI Module
 
    Connect to Host or Vcenter First
    #>


    New-VIProperty -ObjectType VMHost -Name SerialNumber -Value { (Get-EsxCli -VMHost $Args[0]).hardware.platform.get().SerialNumber }
    Get-VMHost | Select-Object Name, SerialNumber | Format-Table
}

Function Get-ToolsAutoUpgradeState {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 06122019
 
    .DESCRIPTION
    Filter out 2003 servers and servers that don't have Vmware Tools installed.
 
    List those that have AutoUpgrade set to manual
 
    .EXAMPLE
    Get-ToolsAutoUpgradeState
 
    .NOTES
    Requires the VMware.PowerCLI Module
    #>


    [CmdletBinding(SupportsShouldProcess)]
    Param (
        [Parameter(Mandatory = $false)][switch]$Unmanaged
    )

    #Filter Out 2003 Servers
    $No2003VMs = Get-VM | Where-Object { $_.Guest -notlike '*2003*' }

    if ($Unmanaged) {
        #Filter for Tools that have Auto Tool upgrade set to Manual
        $ManualUpdateVMs = Get-VM $No2003VMs.name |
        Get-View |
        Where-Object { $_.Config.Tools.ToolsUpgradePolicy -like "manual" } |
        Select-Object name, @{N = 'ToolsUpgradePolicy'; E = { $_.Config.Tools.ToolsUpgradePolicy } }
    }

    else {
        #Get VM's that have tools installed
        $VMsForAutoUpgrade = Get-VM $No2003VMs |
        ForEach-Object { Get-View $_.id } |
        Where-Object { $_.Guest.ToolsVersionStatus -notlike "guestToolsNotInstalled" -or $_.Guest.ToolsVersionStatus -notlike "guestToolsUnmanaged" } |
        Select-Object name, @{Name = 'ToolsVersion'; Expression = { $_.config.tools.toolsversion } }, @{Name = 'ToolStatus'; Expression = { $_.Guest.ToolsVersionStatus } }

        #Filter for Tools that have Auto Tool upgrade set to Manual
        $ManualUpdateVMs = Get-VM $VMsForAutoUpgrade.name |
        Get-View |
        Where-Object { $_.Config.Tools.ToolsUpgradePolicy -like "manual" } |
        Select-Object name, @{N = 'ToolsUpgradePolicy'; E = { $_.Config.Tools.ToolsUpgradePolicy } }
    }

    $ManualUpdateVMs

}

Function Get-VMwareAutomate {
    <#
    .Synopsis
    -Taylor Lee
    Modified 06202019
 
    .Description
    A Functions list for the Powershell Profile
    #>


    Write-Host " "
    Write-Host "VMWare Automate Functions"                                                  -Foregroundcolor green
    Write-Host "Enable-ToolsAutoUpgrade ..Enables AutoUpgrade of VMTools"                -Foregroundcolor cyan
    Write-Host "Get-DRBackup ..Gets csvs of the VM Enviroment"                -ForegroundColor cyan
    Write-Host "Get-HostMemoryDimms ..Gets host memory information"                  -Foregroundcolor cyan
    Write-Host "Get-HostSerialNumber ..Get a host serial number"                      -Foregroundcolor cyan
    Write-Host "Get-ToolsAutoUpgradeState ..Gets VMtools AutoUpgrade Status"               -Foregroundcolor cyan
    Write-Host "Get-VMTools ..Gets VMtools Status"                           -Foregroundcolor cyan
    Write-Host "Invoke-HotAdd ..Invokes enabling HotAdd CPU or Memory"         -Foregroundcolor cyan
    Write-Host "Invoke-Power ..Invokes Power State Changes of Guest or VM"    -Foregroundcolor cyan
    Write-Host "Update-VMTools ..Updates VM tools"                              -Foregroundcolor cyan
    Write-Host " "
}

Function Enable-ToolsAutoUpgrade {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 06132019
 
    .DESCRIPTION
    Filter out 2003 servers and servers that don't have Vmware Tools installed.
 
    All remaining servers will have their tools set to upgrade automatically.
 
    .EXAMPLE
    Enable-ToolsAutoUpgrade
 
    .EXAMPLE
    Include VM's Without Guest Tools Installed
 
    Enable-ToolsAutoUpgrade -Unmanaged
 
    .NOTES
    Requires the VMware.PowerCLI Module
    #>


    [CmdletBinding(SupportsShouldProcess)]
    Param (
        [Parameter(Mandatory = $false)][switch]$Unmanaged
    )

    #Set Error Action to ignor error for Null value VM's
    $ErrorActionPreference = 'SilentlyContinue'

    #Disclaimer
    Write-Host "Servers with a null value for UpgradeAtPowercycle Will be skipped." -ForegroundColor Yellow
    Write-Host "2003 Servers will be Skipped for Compatibility issues" -ForegroundColor Yellow
    Write-Host " "

    #Filter Out 2003 Servers
    $No2003VMs = Get-VM | Where-Object { $_.Guest -notlike '*2003*' }

    if ($Unmanaged) {
        #Filter for Tools that have Auto Tool upgrade set to Manual
        $ManualUpdateVMs = Get-VM $No2003VMs.name |
        Get-View |
        Where-Object { $_.Config.Tools.ToolsUpgradePolicy -like "manual" } |
        Select-Object name, @{N = 'ToolsUpgradePolicy'; E = { $_.Config.Tools.ToolsUpgradePolicy } }

        #Set Tools to upgrade at Power Cycle
        Foreach ($VM in ($ManualUpdateVMs)) {
            Write-Host "Configuring UpgradeAtPowerCycle on: " -ForegroundColor Yellow -NoNewline
            Write-Host $VM.name -ForegroundColor Cyan
            $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
            $vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
            $vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"
            $VMConfig.ReconfigVM($vmConfigSpec)
        }
    }

    else {
        #Get VM's that have tools installed
        $VMsForAutoUpgrade = Get-VM $No2003VMs |
        ForEach-Object { Get-View $_.id } |
        Where-Object { $_.Guest.ToolsVersionStatus -notlike "guestToolsNotInstalled" -or $_.Guest.ToolsVersionStatus -notlike "guestToolsUnmanaged" } |
        Select-Object name, @{Name = 'ToolsVersion'; Expression = { $_.config.tools.toolsversion } }, @{Name = 'ToolStatus'; Expression = { $_.Guest.ToolsVersionStatus } }

        #Filter for Tools that have Auto Tool upgrade set to Manual
        $ManualUpdateVMs = Get-VM $VMsForAutoUpgrade.name |
        Get-View |
        Where-Object { $_.Config.Tools.ToolsUpgradePolicy -like "manual" } |
        Select-Object name, @{N = 'ToolsUpgradePolicy'; E = { $_.Config.Tools.ToolsUpgradePolicy } }

        #Set Tools to upgrade at Power Cycle
        Foreach ($VM in ($ManualUpdateVMs)) {
            Write-Host "Configuring UpgradeAtPowerCycle on: " -ForegroundColor Yellow -NoNewline
            Write-Host $VM.name -ForegroundColor Cyan
            $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
            $vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
            $vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"
            $VMConfig.ReconfigVM($vmConfigSpec)
        }
    }
}

Function Get-VMTools {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 06122019
 
    .DESCRIPTION
    Get Virtual Machines that have outdated VMWare Tools or all Virtual Machine tools versions.
 
    .EXAMPLE
    Get-VMTools
 
    .EXAMPLE
    Show tools versions for all VM's
 
    Get-VMTools -Alltools
 
 
    .EXAMPLE
    Only show VM's with Outdated Tools
 
    Get-VMTools -OutDatedTools
 
    .EXAMPLE
    Show VM's with Outdated Tools and include unmanaged tools
 
    Get-VMTools -OutDatedTools -Unmanaged
 
    .NOTES
    Requires the VMware.PowerCLI Module
    #>


    [CmdletBinding(SupportsShouldProcess)]
    Param (
        [Parameter(Mandatory = $true, ParameterSetName = "AllTools")][Switch] $AllTools,
        [Parameter(Mandatory = $true, ParameterSetName = "OutDatedTools")][Switch] $OutDatedTools,
        [Parameter(Mandatory = $false, ParameterSetName = "OutDatedTools")][Switch] $Unmanaged
    )


    if ($AllTools) {
        Get-VM |
        ForEach-Object { Get-View $_.id } |
        Select-Object name, @{Name = 'ToolsVersion'; Expression = { $_.config.tools.toolsversion } }, @{Name = 'ToolStatus'; Expression = { $_.Guest.ToolsVersionStatus } } |
        Sort-Object Name
    }

    if ($OutDatedTools) {
        if ($Unmanaged) {
            Get-VM |
            ForEach-Object { Get-View $_.id } |
            Where-Object { $_.Guest.ToolsVersionStatus -like 'guestToolsNeedUpgrade' -or $_.Guest.ToolsVersionStatus -like 'guestToolsNotInstalled' } |
            Select-Object name, @{Name = 'ToolsVersion'; Expression = { $_.config.tools.toolsversion } }, @{Name = 'ToolStatus'; Expression = { $_.Guest.ToolsVersionStatus } } |
            Sort-Object Name
        }

        else {
            Get-VM |
            ForEach-Object { Get-View $_.id } |
            Where-Object { $_.Guest.ToolsVersionStatus -like 'guestToolsNeedUpgrade' } |
            Select-Object name, @{Name = 'ToolsVersion'; Expression = { $_.config.tools.toolsversion } }, @{Name = 'ToolStatus'; Expression = { $_.Guest.ToolsVersionStatus } } |
            Sort-Object Name
        }
    }
}

Function Invoke-HotAdd {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 06182019
 
    .DESCRIPTION
    Modify Hotadd settings for a single or all VM's
 
    .EXAMPLE
    Disable Memory HotAdd on all VM's
 
    Invoke-HotAdd -DisableMem
 
    .EXAMPLE
    Disable Memory HotAdd on a single vm
 
    Invoke-HotAdd -DisableMem -VMName ExchangeServer
 
    .NOTES
    Requires the VMware.PowerCLI Module
    #>


    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ParameterSetName = 'Disable Mem Hotadd')][switch]$DisableMem,
        [Parameter(Mandatory = $true, ParameterSetName = 'Disable CPU Hotadd')][switch]$DisableCPU,
        [Parameter(Mandatory = $true, ParameterSetName = 'Enable Mem Hotadd')][switch]$EnableMem,
        [Parameter(Mandatory = $true, ParameterSetName = 'Enable CPU Hotadd')][switch]$EnableCpu,
        [Parameter(Mandatory = $false, ParameterSetName = 'Disable Mem Hotadd')]
        [Parameter(Mandatory = $false, ParameterSetName = 'Disable CPU Hotadd')]
        [Parameter(Mandatory = $false, ParameterSetName = 'Enable Mem Hotadd')]
        [Parameter(Mandatory = $false, ParameterSetName = 'Enable CPU Hotadd')]
        $VMName
    )

    if ($DisableMem) {
        if ($VMName) {
            Write-Host "Configuring $VMName" -ForegroundColor Yellow
            $vmview = Get-VM $VMName | Get-View
            $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
            $extra = New-Object VMware.Vim.optionvalue
            $extra.Key = "mem.hotadd"
            $extra.Value = "false"
            $vmConfigSpec.extraconfig += $extra
            $vmview.ReconfigVM($vmConfigSpec)
        }

        else {
            $vms = Get-VM | Get-View

            foreach ($vm in $vms) {
                Write-Host "Configuring hotadd on: " -ForegroundColor Yellow -NoNewline
                Write-Host $vm.name -ForegroundColor Cyan

                $vmview = Get-VM $vm.name | Get-View
                $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
                $extra = New-Object VMware.Vim.optionvalue
                $extra.Key = "mem.hotadd"
                $extra.Value = "false"
                $vmConfigSpec.extraconfig += $extra
                $vmview.ReconfigVM($vmConfigSpec)
            }
        }
    }

    if ($DisableCPU) {
        if ($VMName) {
            Write-Host "Configuring $VMName" -ForegroundColor Yellow
            $vmview = Get-VM $VMName | Get-View
            $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
            $extra = New-Object VMware.Vim.optionvalue
            $extra.Key = "vcpu.hotadd"
            $extra.Value = "false"
            $vmConfigSpec.extraconfig += $extra
            $vmview.ReconfigVM($vmConfigSpec)
        }

        else {
            $vms = Get-VM | Get-View

            foreach ($vm in $vms) {
                Write-Host "Configuring hotadd on: " -ForegroundColor Yellow -NoNewline
                Write-Host $vm.name -ForegroundColor Cyan

                $vmview = Get-VM $vm.name | Get-View
                $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
                $extra = New-Object VMware.Vim.optionvalue
                $extra.Key = "vcpu.hotadd"
                $extra.Value = "false"
                $vmConfigSpec.extraconfig += $extra
                $vmview.ReconfigVM($vmConfigSpec)
            }
        }
    }

    if ($EnableMem) {
        if ($VMName) {
            WWrite-Host "Configuring $VMName" -ForegroundColor Yellow
            $vmview = Get-VM $VMName | Get-View
            $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
            $extra = New-Object VMware.Vim.optionvalue
            $extra.Key = "mem.hotadd"
            $extra.Value = "true"
            $vmConfigSpec.extraconfig += $extra
            $vmview.ReconfigVM($vmConfigSpec)
        }

        else {
            $vms = Get-VM | Get-View

            foreach ($vm in $vms) {
                Write-Host "Configuring hotadd on: " -ForegroundColor Yellow -NoNewline
                Write-Host $vm.name -ForegroundColor Cyan

                $vmview = Get-VM $vm.name | Get-View
                $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
                $extra = New-Object VMware.Vim.optionvalue
                $extra.Key = "mem.hotadd"
                $extra.Value = "true"
                $vmConfigSpec.extraconfig += $extra
                $vmview.ReconfigVM($vmConfigSpec)
            }
        }
    }

    if ($EnableCpu) {
        Write-Host "Enabling CPU Hotadd will disable vNUMA and effect VM Performance" -ForegroundColor Yellow
        $prompt = Read-Host "Do you wish to continue? (yes/no)"

        if ($prompt -eq 'yes') {
            if ($VMName) {
                Write-Host "Configuring $VMName" -ForegroundColor Yellow
                $vmview = Get-VM $VMName | Get-View
                $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
                $extra = New-Object VMware.Vim.optionvalue
                $extra.Key = "vcpu.hotadd"
                $extra.Value = "true"
                $vmConfigSpec.extraconfig += $extra
                $vmview.ReconfigVM($vmConfigSpec)
            }
        }

        else {
            $vms = Get-VM | Get-View

            foreach ($vm in $vms) {
                Write-Host "Configuring hotadd on: " -ForegroundColor Yellow -NoNewline
                Write-Host $vm.name -ForegroundColor Cyan

                $vmview = Get-VM $vm.name | Get-View
                $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
                $extra = New-Object VMware.Vim.optionvalue
                $extra.Key = "vcpu.hotadd"
                $extra.Value = "true"
                $vmConfigSpec.extraconfig += $extra
                $vmview.ReconfigVM($vmConfigSpec)
            }
        }

        else {
            Write-Host "Enable CPU Hotadd Canceled" -ForegroundColor Yellow
        }
    }
}

function Invoke-Power {
    [CmdletBinding(SupportsShouldProcess)]

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 06172019
 
    .DESCRIPTION
    Use to alter VM Power states and reboot VM's.
 
    .EXAMPLE
    Gracefully Restart the Guest
 
    Invoke-Power -restartguest -VM vmname
 
    .EXAMPLE
    Gracefully shutdown the Guest
 
    Invoke-Power -poweroffguest -VM vmname
 
    .EXAMPLE
    Hard Power Cycle VM
 
    Invoke-Power -powercycle -VM vmname
 
    .EXAMPLE
    Hard Power Off Vm
 
    Invoke-Power -poweroff -VM vmname
 
    .EXAMPLE
    Hard power on VM
 
    Invoke-Power -poweron -VM vmname
 
    .NOTES
    Requires the VMware.PowerCLI Module
    #>


    [CmdletBinding(SupportsShouldProcess)]
    Param (
        [Parameter(Mandatory = $true, ParameterSetName = 'Power Cycle VM')][switch]$powercyclevm,
        [Parameter(Mandatory = $true, ParameterSetName = 'Restart Guest')][switch]$restartguest,
        [Parameter(Mandatory = $true, ParameterSetName = 'Power Off Guest')][switch]$poweroffguest,
        [Parameter(Mandatory = $true, ParameterSetName = 'Power Off VM')][switch]$poweroffvm,
        [Parameter(Mandatory = $true, ParameterSetName = 'Power On VM')][switch]$poweronvm,
        [Parameter(Mandatory = $true, ParameterSetName = 'Power Cycle VM')]
        [Parameter(Mandatory = $true, ParameterSetName = 'Restart Guest')]
        [Parameter(Mandatory = $true, ParameterSetName = 'Power Off Guest')]
        [Parameter(Mandatory = $true, ParameterSetName = 'Power Off VM')]
        [Parameter(Mandatory = $true, ParameterSetName = 'Power On VM')]
        $VM
    )

    if ($powercyclevm) {
        Restart-VM -VM $VM -RunAsync -Confirm:$true
    }

    if ($restartguest) {
        Restart-VMGuest -VM $VM -Confirm:$false
    }

    if ($poweroffguest) {
        Shutdown-VMGuest -VM $VM -Confirm:$false
    }

    if ($poweroffvm) {
        Stop-VM -VM $vm -RunAsync -Confirm:$true
    }

    if ($poweronvm) {
        Start-VM -VM $VM -RunAsync -Confirm:$false
    }
}

Function Update-VMTools {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 06132019
 
    .DESCRIPTION
    Filter out 2003 servers and upgrade VMwaretools on all servers that are not up to date. Does not reboot the VM's.
 
    .EXAMPLE
    Upgrades only tools that are installed an require it. Specify a path for a log file.
 
    Update-VMTools
 
    .EXAMPLE
    Specify a path for a log file and include unmanaged VM's.
 
    Update-VMTools -Unmanaged
 
    .NOTES
    Requires the VMware.PowerCLI Module
    #>


    [CmdletBinding(SupportsShouldProcess)]
    Param (
        [Parameter(Mandatory = $false)][switch]$Unmanaged
    )

    #Set Error Action to ignor errors
    $ErrorActionPreference = 'SilentlyContinue'

    #Filter Out 2003 Servers
    $No2003VMs = Get-VM | Where-Object { $_.Guest -notlike '*2003*' }

    #Disclaimer
    Write-Host "Some VMs will fail to upgrade. Use Get-VMTools to see which VM's fail" -ForegroundColor Yellow
    Write-Host " "

    if ($Unmanaged) {
        #Get VM's that require tools upgrades
        $OutofDateVMs = Get-VM $No2003VMs |
        ForEach-Object { Get-View $_.id } |
        Where-Object { $_.Guest.ToolsVersionStatus -like 'guestToolsNeedUpgrade' -or $_.Guest.ToolsVersionStatus -like 'guestToolsNotInstalled' } |
        Select-Object name, @{Name = 'ToolsVersion'; Expression = { $_.config.tools.toolsversion } }, @{Name = 'ToolStatus'; Expression = { $_.Guest.ToolsVersionStatus } }

        #Update Tools with no Reboot
        ForEach ($VM in $OutOfDateVMs) {
            Write-Host "Upgrading VMWareTools On: " -ForegroundColor Yellow -NoNewline
            Write-Host $VM.name -ForegroundColor Cyan
            Update-Tools -NoReboot -VM $VM.Name
        }
    }

    else {
        #Get VM's that require tools upgrades and filter unmanaged VM's
        $OutofDateVMs = Get-VM $No2003VMs |
        ForEach-Object { Get-View $_.id } |
        Where-Object { $_.Guest.ToolsVersionStatus -like 'guestToolsNeedUpgrade' } |
        Select-Object name, @{Name = 'ToolsVersion'; Expression = { $_.config.tools.toolsversion } }, @{Name = 'ToolStatus'; Expression = { $_.Guest.ToolsVersionStatus } }

        #Update Tools with no Reboot
        ForEach ($VM in $OutOfDateVMs) {
            Write-Host "Upgrading VMWareTools On: " -ForegroundColor Yellow -NoNewline
            Write-Host $VM.name -ForegroundColor Cyan
            Update-Tools -NoReboot -VM $VM.Name
        }
    }

}