<# .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 { } }