UMN-Virt.psm1

#requires -Modules VMware.VimAutomation.Core

function Remove-StuckSnapshot {
    <#
    .DESCRIPTION
        This script will remove a stuck snapshot from a VM or list of VMs
    .PARAMETER Name
        The name of the VM to remove the snapshot from
    .PARAMETER VM
        The VM object to remove the snapshot from
    .EXAMPLE
        Remove-StuckSnapshot -Name VM1
        This will remove the stuck snapshot from VM1
    .EXAMPLE
        Get-VM | Where-Object { $_.Extensiondata.Runtime.ConsolidationNeeded }| Remove-StuckSnapshot
        This will remove the stuck snapshot from all VMs

    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [string[]]$Name,
        [Parameter(ValueFromPipeline)]
        [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]]$VM
    )
    begin {
        if ($Name) {
            $VM = Get-VM $Name
        }

    }
    process {
        if (-not $VM) {
            Write-Error -ErrorAction Stop "No VMs found"
        }
        if ( -not $vm.ExtensionData.Runtime.ConsolidationNeeded) {
            Write-Warning "No stuck snapshots found, consolidation is not needed"
            return
        }
        foreach ($VMName in $VM) {
            Write-Warning "Removing stuck snapshot from $VMName"
            $snapshot = $VM | New-Snapshot -Name "StuckSnapshot removal" -Description "StuckSnapshot removal"
            $snapshot | Remove-Snapshot -RemoveChildren -Confirm:$false
        }
    }
    end {}
}

function Set-ClusterSSH {
    # enables or disables ssh on an entire cluster
    # can pipe cluster object in, or can pass the cluster name
    param(
        [Parameter (Mandatory = $true,
            ValueFromPipeline = $true)]
        [String]$ClusterName,
        [parameter(Mandatory = $true,
            ParameterSetName = 'enableSet')]
        [Switch]$Enable,
        [parameter(Mandatory = $true,
            ParameterSetName = 'disableSet')]
        [Switch]$Disable
    )
    $cluster = Get-Cluster $ClusterName
    if ($cluster) {
        if ($Enable) {
            $cluster | Get-VMHost | Get-VMHostService | Where-Object { ($_.Key -eq 'TSM-SSH') } | Start-VMHostService -Confirm:$false

        }
        elseif ($Disable) {
            $cluster | Get-VMHost | Get-VMHostService | Where-Object { ($_.Key -eq 'TSM-SSH') -and ($_.running) } | Stop-VMHostService -Confirm:$false
        }
    }
}

function Get-VGPUVM {
    Get-VM | Select-Object name, @{n = 'cluster'; e = { $_.vmhost.parent } }, @{n = 'gpu'; e = { $_.ExtensionData.Config.Hardware.Device.Backing.vgpu } } | Where-Object { $_.gpu }
}

function Get-ActiveMigrations {
    # get active vmotions based on active tasks
    $runningTasks = Get-Task -Status Running | Where-Object { $_.Name -eq 'RelocateVM_Task' }
    $runningTasks | ForEach-Object -Process {
        $vm = Get-VM -Id $_.ObjectId
        $runningTasks | Select-Object @{N = 'Name'; E = { $vm.Name } }, @{N = 'Task'; E = { $_.Name } }, @{N = 'Progress'; E = { $_.PercentComplete } }, @{N = 'VMotionTime'; E = { Get-Date -Date $_.StartTime } }, @{N = 'VMotionMinutes'; E = { ((Get-Date) - (Get-Date -Date $_.startTime)).Minutes } }
    }
}

function Get-RunningSSH {
    Get-Cluster | Get-VMHost | Get-VMHostService | Where-Object { ($_.Key -eq 'TSM-SSH') -and ($_.running) } | Format-Table -Property vmhost, label, running
}
function Stop-AllSSH {
    Get-Cluster | Get-VMHost | Get-VMHostService | Where-Object { ($_.Key -eq 'TSM-SSH') -and ($_.running) } | Stop-VMHostService
}
function Get-AllSnapshotsInfo {
    Get-VM | Get-Snapshot | Select-Object VM, Name, Description, Created, SizeMB
}
function Get-AllSnapshots {
    Get-VM | Get-Snapshot
}
function Get-AssetInfo {
    param(
        [Parameter (ValueFromPipeline = $true)]
        [String]$ClusterName = '*'
    )
    begin {}
    process {
        Get-VMHost -Location $ClusterName |
        Select-Object name,
        @{n = 'UMN_Asset_Tag'; e = { $_.CustomFields['UMNAssetTag'] } },
        @{N = 'Service_Tag'; E = { ($_ | Get-View).Summary.Hardware.OtherIdentifyingInfo[3].IdentifierValue } }
    }
    end {}
}
function Get-ClusterCores {
    Get-Cluster | Select-Object Name,@{N="TotalSockets";E={($_.ExtensionData.Summary.NumHosts * 2)};},@{N="TotalCores";E={$_.ExtensionData.Summary.NumCpuCores}}
}
function Get-DeletedVMEvents {
    Get-VIEventPlus -Start ((Get-Date).adddays(-30)) -EventType 'VmRemovedEvent' | Select-Object @{Name = 'VMName'; Expression = { $_.vm.name } }, CreatedTime, UserName, fullFormattedMessage
}

function Get-VMByMac {
    param(
        [Parameter (Mandatory = $true)]
        [String]$MacAddress
    )
    (Get-VM | Get-NetworkAdapter |
        Where-Object {$_.MacAddress -eq $MacAddress }).Parent
}

Function Get-VMByIP {
    param(
        [Parameter (Mandatory = $true)]
        [String]$IPAddress
    )
    (Get-VM | Where-Object {$_.Guest.IPAddress -contains $IPAddress })
}


function Get-OldHardwareVM {
    <#
    .DESCRIPTION
        This script will return a list of VMs with the oldest hardware version
    .PARAMETER Cluster
        The cluster/s to search for VMs [default: Hosting-01, XTR]
    .PARAMETER OldestCount
        The number of oldest hardware versions to return [default: 2]
    .PARAMETER Department
        Limit the search for VMs to a specific department
    .EXAMPLE
        Get-OldHardwareVM -Cluster Hosting-01 Department 'Virt'
        This will return a list of VMs with the 2 oldest hardware versions in the Hosting-01 cluster
    #>

    param(
        [string[]]$Cluster = @('Hosting-01', 'XTR'),
        [int]$OldestCount = 2,
        [string]$Department
    )

    if ($Department){
        $TagName = Get-Tag -Category 'Department' | Where-Object {$_.name -like $Department}
        $AllVMs = Get-Cluster $Cluster | Get-VM -Tag $TagName
    } else {
        $AllVMs = get-cluster $Cluster | Get-VM
    }

    $HardwareVersion = $AllVMs.HardwareVersion | Sort-Object -Unique | Sort-Object -Top $OldestCount
    $VMs = $AllVMs | Where-Object { $HardwareVersion -contains $_.HardwareVersion } | Sort-Object -Property Name

    $List = @()
    Write-Host "Gathering Information for $($VMs.Count) VMs with hardware version $($HardwareVersion -join ', ')"

    foreach ($VM in $VMs){
        Write-Host -NoNewline "."
        $Cesi = Get-Cesi -VM $VM
        $Info = [PSCustomObject]@{
            Name = $VM.Name
            HardwareVersion = $VM.HardwareVersion
            Unit = $Cesi.DepartmentId
            Contacts = $Cesi.Contacts
            WinRequestors = $Cesi.WinRequestors
            LinuxRequestors = $Cesi.LinuxRequestors
            SMERequestors = $Cesi.SMERequestors
        }
        $List += $Info
    }

    Write-Host "`nFound $($List.Count) VMs with hardware version $($HardwareVersion -join ', ')"

    return $List
}