Files
Backup/_NDGOV_WindowsTeam/ITD.Infra-VMware.Administration/Helpers/ITD.Infra-VMware.Administration.old
T
Zack Meier 1d304511b8 update
2026-04-15 15:45:50 -05:00

688 lines
22 KiB
Plaintext

<#
.Synopsis
Changes Portgroup on all NICs on specified VMs
.EXAMPLE
Set-ITDVMwareVMNicPortGroup -Computer itdsrv1.nd.gov -Vlan 1394 -Credential $AdminCred
#>
function Set-ITDVMwareVMNicPortGroup {
[CmdletBinding()]
Param
(
[Parameter(Mandatory = $true)]
[string[]]
$ComputerName,
[Parameter(Mandatory = $true)]
[int]
$Vlan,
[PSCredential]
$Credential
)
Begin {
Connect-ITDvCenter -Credential $Credential
Write-Verbose "Connected to: $global:DefaultVIServers"
If ($global:DefaultVIServers.Count -gt 0) {
Write-Verbose "connected to VI server(s)"
}
Else {
Write-Warning "not connected to any VIservers, stopping script"
break
break
}
$AvailablePortGroup = Get-VirtualPortGroup -WarningAction SilentlyContinue
}
Process {
ForEach ($c in $ComputerName) {
Write-Verbose "[$c]:Start"
$CurrentVM = $null
$CurrentVMs = $null
$Datacenter1 = $null
$Datacenter2 = $null
$DestinationFolder = $null
$CurrentDatacenter = $null
$CurrentVMs = Get-VM -Name $c -ErrorAction SilentlyContinue
If ($CurrentVMs.Count -lt 1) {
Write-Warning "[$c]:VM name not found, please check it and try again ******"
}
Else {
If ($CurrentVMs.Count -gt 2) {
Write-Warning "[$c]:More than two results found, process this VM manually"
}
Else {
If ($CurrentVMs.Count -eq 2) {
Write-Verbose "[$c]:Two results found"
$Datacenter1 = ($CurrentVMs[0] | Get-Datacenter).Name
$Datacenter2 = ($CurrentVMs[1] | Get-Datacenter).Name
Write-Verbose "[$c]:Check for SRM"
If ( ( ($Datacenter1 -eq "Primary Datacenter") -or ($Datacenter2 -eq "Primary Datacenter") ) -and ( ($Datacenter1 -eq "Secondary Datacenter") -or ($Datacenter2 -eq "Secondary Datacenter") ) ) {
Write-Warning "[$c]:One result in both Primary and Secondary Datacenters, assuming SRM and continuing"
If ($Datacenter1 -eq "Primary Datacenter") {
$CurrentVM = $CurrentVMs[0]
}
If ($Datacenter2 -eq "Primary Datacenter") {
$CurrentVM = $CurrentVMs[1]
}
}
Else {
Write-Warning "[$c]:Exactly two results in the same datacenter... Congratulations, you've acheieved the impossible."
break
}
}
Else {
Write-Verbose "[$c]:One match found"
$CurrentVM = $CurrentVMs
}
If ($CurrentVM) {
$CurrentDatacenter = ($CurrentVM | Get-Datacenter).Name
Switch ($CurrentDatacenter) {
"Primary Datacenter" {
$VirtualSwitch = "PDC"
}
"Secondary Datacenter" {
$VirtualSwitch = "SDC"
}
}
$VLANsearch = '_' + $VLAN
$VMVLAN = $AvailablePortGroup | `
Where-Object { $_.Name -Like "*$VLANsearch" -and $_.VirtualSwitch -like "*$VirtualSwitch*" }
$CurrentVM | Get-NetworkAdapter | `
Set-NetworkAdapter -NetworkName $VMVLAN -Confirm:$false -RunAsync
}
}
}
Write-Verbose "[$c]:End Remove"
}
}
End {
}
}
<#
.Synopsis
Creates new distributed virtual port group with name standard
.DESCRIPTION
Long description
.EXAMPLE
New-ITDVMwarePortGroup -CIDR 10.2.60.0/23 -VLAN 1394
.EXAMPLE
New-ITDVMwarePortGroup -CIDR 10.2.60.0/23 -VLAN 1394 -Credential $Credential
#>
function New-ITDVMwarePortGroup {
[CmdletBinding()]
Param
(
[string]
$CIDR,
[int]
$VLAN,
[PSCredential]
$Credential
)
Begin {
Connect-ITDvCenter -Credential $Credential
$BismarckVDSwitch = 'dvSwitch-PDC-Data'
$MandanVDSwitch = 'dvSwitch-SDC-Data'
$IP = $CIDR.split('/')[0]
$Mask = $CIDR.split('/')[1]
$VLANstring = $VLAN.ToString('0000')
}
Process {
#$PGName="dvPG-$CIDR" + "_" + "$VLAN"
$PGName = "dvPG_" + $VLANstring + "_" + $IP + "_" + $Mask
Get-VDSwitch -Name $BismarckVDSwitch | New-VDPortgroup -Name $PGName -NumPorts 1 -VlanId $VLAN
Get-VDSwitch -Name $BismarckVDSwitch | Get-VDPortgroup | Where-Object { $_.Name -like ("*" + "_" + $VLAN) } | Get-VDUplinkTeamingPolicy | Set-VDUplinkTeamingPolicy -FailoverDetectionPolicy BeaconProbing
Get-VDSwitch -Name $BismarckVDSwitch | Get-VDPortgroup | Where-Object { $_.Name -like ("*" + "_" + $VLAN) } | Get-VDPortgroupOverridePolicy | Set-VDPortgroupOverridePolicy -BlockOverrideAllowed $false -ResetPortConfigAtDisconnect $false
Get-VDSwitch -Name $MandanVDSwitch | New-VDPortgroup -Name $PGName -NumPorts 1 -VlanId $VLAN
Get-VDSwitch -Name $MandanVDSwitch | Get-VDPortgroup | Where-Object { $_.Name -like ("*" + "_" + $VLAN) } | Get-VDUplinkTeamingPolicy | Set-VDUplinkTeamingPolicy -FailoverDetectionPolicy BeaconProbing
Get-VDSwitch -Name $MandanVDSwitch | Get-VDPortgroup | Where-Object { $_.Name -like ("*" + "_" + $VLAN) } | Get-VDPortgroupOverridePolicy | Set-VDPortgroupOverridePolicy -BlockOverrideAllowed $false -ResetPortConfigAtDisconnect $false
}
End {
}
}
function Find-ITDVMDatastoreClusterMaxAverageDatastoreFreeSpace ($Cluster) {
$MaxDsCFreeSpaceAvgPerDiskGB = $null
$MaxDsCName = $null
$AvailableDsC = Get-DatastoreCluster | Where-Object Name -Like *$Cluster*
$AvailableDsCCount = ($AvailableDsC | Measure-Object).Count
Write-Verbose "Found $AvailableDsCCount datastore clusters matching $Cluster"
ForEach ($d in $AvailableDsC) {
$DsCFreeSpaceInfo = Get-DatastoreCluster -Name $d.Name | Get-Datastore | Select-Object FreeSpaceGB | Measure-Object -Property FreeSpaceGB -Average -Sum
$CurrentDsCFreeSpaceAvgPerDiskGB = $DsCFreeSpaceInfo.Average
# If first in datastore clusters to check
If ($MaxDsCFreeSpaceAvgPerDiskGB -eq $null) {
Write-Verbose "First datastore cluster, default max datastore cluster"
$MaxDsCFreeSpaceAvgPerDiskGB = $CurrentDsCFreeSpaceAvgPerDiskGB
$MaxDsCName = $d.Name
}
# Is current Ds cluster avg free space per datastore is larger than max
If ($CurrentDsCFreeSpaceAvgPerDiskGB -gt $MaxDsCFreeSpaceAvgPerDiskGB) {
Write-Verbose "Current larger than Max"
$MaxDsCFreeSpaceAvgPerDiskGB = $CurrentDsCFreeSpaceAvgPerDiskGB
$MaxDsCName = $d.Name
}
Write-Verbose "CurrentDsCName: $d"
Write-Verbose "CurrentDsCFreeSpaceAvgPerDiskGB = $CurrentDsCFreeSpaceAvgPerDiskGB"
Write-Verbose "MaxDsCFreeSpaceAvgPerDiskGB = $MaxDsCFreeSpaceAvgPerDiskGB"
}
Write-Verbose "Return MaxDsCFreeSpaceName: $MaxDsCName"
return $MaxDsCName
}
<#
.SYNOPSIS
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
.INPUTS
Inputs to this cmdlet (if any)
.OUTPUTS
Output from this cmdlet (if any)
.NOTES
General notes
.COMPONENT
The component this cmdlet belongs to
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
The functionality that best describes this cmdlet
#>
function Get-ITDVMwareSharePointSnapshotRequestList {
[CmdletBinding()]
Param
(
[PSCredential]
$Credential
)
begin {
$InvokeWebRequestParams = @{ }
If ($Credential) { $InvokeWebRequestParams += @{Credential = $Credential } }
Else { $InvokeWebRequestParams += @{UseDefaultCredentials = $true } }
$URL = "https://share.nd.gov/itd/Computer-Systems/Distributed-Systems/VMWare/_api/lists/getbytitle('VMWare-Snapshots')/items" + '?$top=10000' + '&$select=ID,Title,DateTime,Duration,Author/Name,Author/Title,Author/EMail,Status,NotifyEmail&$expand=Author/Id'
$InvokeWebRequestParams += @{
Uri = $URL
Method = "Get"
Headers = @{ "Accept" = "application/json;odata=verbose" }
}
$List = (Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
#$List = (Invoke-WebRequest -Uri $URL -Method Get -UseDefaultCredentials -headers @{ "Accept" = "application/json;odata=verbose" }) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
}
process {
}
end {
$List.d.results
}
}
function Get-ITDVMwareSharePointSnapshotRequestListTst {
[CmdletBinding()]
Param
(
[PSCredential]
$Credential
)
begin {
$InvokeWebRequestParams = @{ }
If ($Credential) { $InvokeWebRequestParams += @{Credential = $Credential } }
Else { $InvokeWebRequestParams += @{UseDefaultCredentials = $true } }
$URL = "https://testshare.nd.gov/itd/Computer-Systems/Distributed-Systems/VMWare/_api/lists/getbytitle('VMWare-Snapshots')/items" + '?$top=10000' + '&$select=ID,Title,DateTime,Duration,Author/Name,Author/Title,Author/EMail,Status,NotifyEmail&$expand=Author/Id'
$InvokeWebRequestParams += @{
Uri = $URL
Method = "Get"
Headers = @{ "Accept" = "application/json;odata=verbose" }
}
$List = (Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
#$List = (Invoke-WebRequest -Uri $URL -Method Get -UseDefaultCredentials -headers @{ "Accept" = "application/json;odata=verbose" }) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
}
process {
}
end {
$List.d.results
}
}
<#
.SYNOPSIS
Runs Unmap cmds from VMhost to cleanup dirty data blocks on A9K storage
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
.INPUTS
Inputs to this cmdlet (if any)
.OUTPUTS
Output from this cmdlet (if any)
.NOTES
General notes
.COMPONENT
The component this cmdlet belongs to
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
The functionality that best describes this cmdlet
#>
function Start-ITDVMwareDatastoreUnmap {
[CmdletBinding()]
param
(
[string[]]
$Datastore,
[PSCredential]
$Credential
)
begin {
$ConnectITDvCenterParams = @{ }
If ($Credential) { $ConnectITDvCenterParams += @{Credential = $Credential } }
Connect-ITDvCenter @ConnectITDvCenterParams
}
process {
$Clusters = Get-Datacenter Secondary*, Primary* | Get-Cluster
ForEach ($Cluster in $Clusters) {
$esxcli = $null
$Datastores = $null
$VMHost = $null
$Datastores = $Cluster | Get-Datastore | Where-Object { $_.Name -notlike "*TEMPL*" -and $_.Name -like "*$Datastore*" -and $_.Name -like "*A9K*" } | Sort-Object Name
$VMHost = $Cluster | Get-VMHost | Where-Object ConnectionState -EQ "Connected" | Select-Object -First 1
$esxcli = Get-EsxCli -VMHost $VMHost
ForEach ($ds in $Datastores) {
$TimeStamp = Get-Date -UFormat "%Y%m%d%H%M%S"
Write-Warning "[$ds]:Start $TimeStamp on $VMHost"
$esxcli.storage.vmfs.unmap($null, $ds, $null)
}
}
}
end {
}
}
<#
.SYNOPSIS
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
.INPUTS
Inputs to this cmdlet (if any)
.OUTPUTS
Output from this cmdlet (if any)
.NOTES
General notes
.COMPONENT
The component this cmdlet belongs to
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
The functionality that best describes this cmdlet
#>
function Remove-ITDVMwareDatastoreStep1 {
[CmdletBinding()]
Param
(
[int[]]
$LunId,
[PSCredential]
$vCenterCredential,
[PSCredential]
$SharePointCredential
)
begin {
$ConnectITDvCenterParams = @{ }
If ($vCenterCredential) { $ConnectITDvCenterParams += @{Credential = $vCenterCredential } }
Connect-ITDvCenter @ConnectITDvCenterParams
$VMwareList = Get-Datastore
$GetITDVMwareSharePointDatastoreRecordParams = @{ }
If ($SharePointCredential) { $GetITDVMwareSharePointDatastoreRecordParams = @{Credential = $SharePointCredential } }
#$SharePointList = Get-ITDVMwareSharePointDatastoreRecord | select *,@{n='Name';e={$_.Title}}
$SharePointList = Get-ITDVMwareSharePointDatastoreRecord @GetITDVMwareSharePointDatastoreRecordParams | Select-Object *, @{n = 'Name'; e = { $_.Title } }
}
process {
$DatastoreRemovalSuccess = @()
$DatastoreRemovalFailure = @()
ForEach ($Id in $LunId) {
$DatastoreID = $null
$Datastore = $null
$Datastores = Get-Datastore | Where-Object Name -Like ("*_" + $Id + "_*")
ForEach ($Datastore in $Datastores) {
$SharePointRecord = $null
$DatastoreHosts = $Datastore | Get-VMHost
$VMHostCanonicalName = (Get-ScsiLun -VmHost ($DatastoreHosts | Select-Object -First 1) | Where-Object RuntimeName -Like "*L$Id*").CanonicalName
$SharePointRecord = ($SharePointList | Where-Object Title -EQ $Datastore.Name)
If ($SharePointRecord.ExtentName -eq $VMHostCanonicalName) {
Write-Verbose ($Datastore.Name + " *** " + $VMHostCanonicalName + " *** CanonicalName accurate in SharePoint, continuing with unmount")
try {
Get-Datastore $Datastore #| Unmount-Datastore
$DatastoreHosts | Select-Object -First 1 | Remove-Datastore $Datastore -Confirm:$false -RunAsync
$DatastoreRemovalSuccess += $Datastore.Name
}
catch {
$DatastoreRemovalFailure += $Datastore.Name
}
}
else {
Write-Error ($Datastore.Name + " *** " + " *** CanonicalName mismatch with SharePoint Record")
}
}
}
}
end {
}
}
<#
.SYNOPSIS
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
.INPUTS
Inputs to this cmdlet (if any)
.OUTPUTS
Output from this cmdlet (if any)
.NOTES
General notes
.COMPONENT
The component this cmdlet belongs to
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
The functionality that best describes this cmdlet
#>
function Remove-ITDVMwareDatastoreStep3 {
[CmdletBinding()]
Param
(
[int[]]
$LunId,
[PSCredential]
$vCenterCredential,
[PSCredential]
$SharePointCredential
)
begin {
$ConnectITDvCenterParams = @{ }
If ($vCenterCredential) { $ConnectITDvCenterParams += @{Credential = $vCenterCredential } }
Connect-ITDvCenter @ConnectITDvCenterParams
$VMwareList = Get-Datastore
$GetITDVMwareSharePointDatastoreRecordParams = @{ }
If ($SharePointCredential) { $GetITDVMwareSharePointDatastoreRecordParams = @{Credential = $SharePointCredential } }
#$SharePointList = Get-ITDVMwareSharePointDatastoreRecord | select *,@{n='Name';e={$_.Title}}
$SharePointList = Get-ITDVMwareSharePointDatastoreRecord @GetITDVMwareSharePointDatastoreRecordParams | Select-Object *, @{n = 'Name'; e = { $_.Title } }
}
process {
$DeviceUidToRemove = @()
ForEach ($Id in $LunId) {
$DeviceUidToRemove += $SharePointList | Where-Object Name -Like "*$Id*" | Select-Object *, @{n = 'HostCluster'; e = { $_.Name.split('_')[0] -replace "VM" } }
}
$DeviceUidToRemove = $DeviceUidToRemove | Sort-Object HostCluster
If (@($DeviceUidToRemove).count -ne @($LunId).count) { Write-Error "LunId and datastore search count mismatch, verify SharePoint manually before continuing" }
else {
#confirmation prompt
Write-Warning "The following SAN volumes will be detached from the VMware hosts. Please confirm this list is correct:"
$DeviceUidToRemove | ForEach-Object { Write-Warning ($_.Name + " *** " + $_.ExtentName) }
Pause
$HostClusters = $DeviceUidToRemove | Group-Object HostCluster
ForEach ($HostCluster in $HostClusters) {
$VMHosts = Get-Cluster $HostCluster.Name | Get-VMHost
ForEach ($DeviceUid in @($DeviceUidToRemove | Where-Object HostCluster -EQ $HostCluster)) {
$removeUID = Get-ScsiLun -VmHost $VMHosts | Where-Object CanonicalName -EQ $DeviceUid | Select-Object -First 1
If ($removeUID) {
foreach ($VMHost in $VMHosts) {
$esxcli = Get-EsxCli -VMHost $VMHost -V2
#$esxcli.storage.core.device.detached.remove.invoke(@{device = $removeUID})
}
}
}
Get-VMHostStorage -VMHost $VMhosts -RescanAllHba -RescanVmfs
}
}
}
end {
}
}
function Get-ITDVMwareAlarmState {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ParameterSetName = 'Entity'
)]
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]
$Entity,
[switch]
$Recurse = $false
)
begin {
}
process {
$Entity = Get-Inventory -Id $Entity.Id
if ($Recurse) {
$VMObjects = @($Entity)
$VMObjects += Get-Inventory -Location $Entity
}
else {
$VMObjects = $Entity
}
$VMObjects | Select-Object Name, `
@{N = "Type"; E = { $_.GetType().Name.Replace("Impl", "").Replace("Wrapper", "") } }, `
@{N = "Alarm actions enabled"; E = { $_.ExtensionData.alarmActionsEnabled } }
}
end {
}
}
function Set-ITDVMwareAlarmState {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]
$Entity,
[switch]
$Enabled,
[switch]
$Recurse
)
begin {
$alarmMgr = Get-View AlarmManager
}
process {
if ($Recurse) {
$VMObjects = @($Entity)
$VMObjects += Get-Inventory -Location $Entity
}
else {
$VMObjects = $Entity
}
$VMObjects | ForEach-Object {
$alarmMgr.EnableAlarmActions($_.Extensiondata.MoRef, $Enabled)
}
}
end {
}
}
function Expand-ITDVMwareDatastore {
param (
[string[]]
$LunId
)
$HostsToRescan = @()
ForEach ($Id in $LunId) {
$Datastore = Get-Datastore "*$Id*"
$HostSystem = Get-View -Id ($Datastore.ExtensionData.Host | Select-Object -First 1 | Select-Object -ExpandProperty Key)
$DatastoreSystem = Get-View -Id $HostSystem.ConfigManager.DatastoreSystem
$ExpandOptions = $DatastoreSystem.QueryVmfsDatastoreExpandOptions($Datastore.ExtensionData.MoRef)
$DatastoreSystem.ExpandVmfsDatastore($Datastore.ExtensionData.MoRef, $ExpandOptions.spec)
$HostsToRescan += $Datastore | Get-VMHost | Sort-Object Name
}
}
function New-ITDVMwareHostScratchFolder {
[CmdletBinding()]
param (
[ValidateSet("Bismarck", "Mandan")]
[string]
$Site,
[string]
$VMHost
)
Begin {
}
Process {
switch ($Site) {
"Bismarck" {
$vCenter = "itdvmvc1.nd.gov@443"
$Datacenter = "Primary Datacenter"
$Datastore = "VMALL1_006_FS92_SCRATCH"
}
"Mandan" {
$vCenter = "itdvmvc2.nd.gov@443"
$Datacenter = "Secondary Datacenter"
$Datastore = "VMALL2_007_FS92_SCRATCH"
}
}
New-Item -Path "vmstores:\$vCenter\$Datacenter\$Datastore\scratch" -Name $VMHost -ItemType Directory
}
End {
}
}
function Set-ITDVMwareHostMaintenance {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string[]]
$Name,
[ValidateSet("Enter", "Exit")]
[string]
$Status
)
Begin {
}
Process {
ForEach ($n in $Name) {
$VMHost = $null
$VMHost = Get-VMHost $n
$alarmMgr = Get-View AlarmManager -Server $VIServer
switch ($Status) {
"Enter" {
$VMHost | Set-VMHost -State "Maintenance" -RunAsync
$ViServer = $VMHost.Uid.split('@')[1].split(':')[0]
$alarmMgr.EnableAlarmActions($VMHost.ExtensionData.MoRef, $false)
}
"Exit" {
$VMHost | Set-VMHost -State "Connected" -RunAsync
$ViServer = $VMHost.Uid.split('@')[1].split(':')[0]
$alarmMgr.EnableAlarmActions($VMHost.ExtensionData.MoRef, $true)
}
}
}
Get-VMHost $Name | Select-Object Name, ConnectionState, @{n = 'Alarms'; e = { $_.ExtensionData.AlarmActionsEnabled } }
}
End {
}
}