diff --git a/Modules/VMware.HCX/VMware.HCX.psd1 b/Modules/VMware.HCX/VMware.HCX.psd1 index e869f17..63af019 100644 --- a/Modules/VMware.HCX/VMware.HCX.psd1 +++ b/Modules/VMware.HCX/VMware.HCX.psd1 @@ -36,6 +36,7 @@ Description = 'PowerShell Module for Managing Hybrid Cloud Extension (HCX) on VM PowerShellVersion = '6.0' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. + FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Get-HcxEndpoint', 'New-HcxMigration', 'Get-HcxMigration', 'Connect-HcxVAMI', 'Get-HcxVCConfig', 'Set-HcxLicense', 'Set-HcxVCConfig', 'Get-HcxNSXConfig', 'Set-HcxNSXConfig', 'Get-HcxCity', 'Get-HcxLocation', 'Set-HcxLocation', 'Get-HcxRoleMapping', 'Set-HcxRoleMapping', 'Get-HcxProxy', 'Set-HcxProxy', 'Remove-HcxProxy', 'Connect-HcxCloudServer', 'Get-HCXCloudActivationKey', diff --git a/Modules/VMware.HCX/VMware.HCX.psm1 b/Modules/VMware.HCX/VMware.HCX.psm1 index 85640ae..781e0fe 100644 --- a/Modules/VMware.HCX/VMware.HCX.psm1 +++ b/Modules/VMware.HCX/VMware.HCX.psm1 @@ -453,12 +453,23 @@ Function Get-HcxMigration { Get-HcxMigration -MigrationId #> Param ( - [Parameter(Mandatory=$false)][String]$MigrationId, + [Parameter(Mandatory=$false)][String[]]$MigrationId, [Switch]$RunningMigrations ) If (-Not $global:hcxConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxManager " } Else { - $spec = @{} + If($PSBoundParameters.ContainsKey("MigrationId")){ + $spec = @{ + filter = @{ + migrationId = $MigrationId + } + paging =@{ + pageSize = $MigrationId.Count + } + } + } Else { + $spec = @{} + } $body = $spec | ConvertTo-Json $hcxQueryUrl = $global:hcxConnection.Server + "/migrations?action=query" @@ -468,10 +479,10 @@ Function Get-HcxMigration { $requests = Invoke-WebRequest -Uri $hcxQueryUrl -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing } - $migrations = ($requests.content | ConvertFrom-Json).rows - if($PSBoundParameters.ContainsKey("MigrationId")){ - $migrations = $migrations | where { $_.migrationId -eq $MigrationId } + $migrations = ($requests.content | ConvertFrom-Json).items + } else { + $migrations = ($requests.content | ConvertFrom-Json).rows } if($RunningMigrations){ @@ -559,16 +570,22 @@ Function Get-HcxVCConfig { #> If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { $vcConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/vcenter" + $pscConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/lookupservice" if($PSVersionTable.PSEdition -eq "Core") { $vcRequests = Invoke-WebRequest -Uri $vcConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + $ssoRequests = Invoke-WebRequest -Uri $pscConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck } else { $vcRequests = Invoke-WebRequest -Uri $vcConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + $ssoRequests = Invoke-WebRequest -Uri $pscConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing } $vcData = ($vcRequests.content | ConvertFrom-Json).data.items + $ssoData = ($ssoRequests.content | ConvertFrom-Json).data.items $tmp = [pscustomobject] @{ Name = $vcData.config.name; + UserName = $vcData.Config.userName + LookupServiceUrl = $ssoData.config.lookupServiceUrl Version = $vcData.config.version; Build = $vcData.config.buildNumber; UUID = $vcData.config.vcuuid; @@ -578,6 +595,38 @@ Function Get-HcxVCConfig { } } +Function Get-HcxLicense { + <# + .NOTES + =========================================================================== + Created by: Mark McGilly + Date: 4/29/2019 + Organization: Liberty Mutual Insurance + =========================================================================== + + .SYNOPSIS + Returns the license key that is registered with HCX Manager + .DESCRIPTION + This cmdlet returns the license key registered with HCX Manager + .EXAMPLE + Get-HcxLicense + #> + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $hcxConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/hcx" + + if($PSVersionTable.PSEdition -eq "Core") { + $licenseRequests = Invoke-WebRequest -Uri $hcxConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $licenseRequests = Invoke-WebRequest -Uri $hcxConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + $license = ($licenseRequests.content | ConvertFrom-Json).data.items + if($licenseRequests) { + $license.config.activationKey + } + } +} + Function Set-HcxLicense { <# .NOTES @@ -789,6 +838,7 @@ Function Get-HcxNSXConfig { $tmp = [pscustomobject] @{ Name = $nsxData.config.url; + UserName = $nsxData.config.userName Version = $nsxData.config.version; HCXUUID = $nsxData.config.uuid; } @@ -1200,6 +1250,7 @@ Function Set-HcxProxy { [Parameter(Mandatory=$True)]$ProxyPort, [Parameter(Mandatory=$False)]$ProxyUser, [Parameter(Mandatory=$False)]$ProxyPassword, + [Parameter(Mandatory=$False)]$ProxyExclusions, [Switch]$Troubleshoot ) @@ -1214,7 +1265,7 @@ Function Set-HcxProxy { config = @{ proxyHost = "$ProxyServer"; proxyPort = "$ProxyPort"; - nonProxyHosts = ""; + nonProxyHosts = "$ProxyExclusions"; userName = "$ProxyUser"; password = "$ProxyPassword"; } diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index c150c5f..a73fc56 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -94,6 +94,159 @@ function Get-VcenterID { return $virtualCenterId } +function Get-HVvCenterServer { + <# + .Synopsis + Gets a list of all configured vCenter Servers + + .DESCRIPTION + Queries and returns the vCenter Servers configured for the pod of the specified HVServer. + + .PARAMETER HvServer + Reference to Horizon View Server to query the virtual machines from. If the value is not passed or null then + first element from global:DefaultHVServers would be considered inplace of hvServer + + .PARAMETER Name + A string value to query a vCenter Server by Name, if it is known. + + .EXAMPLE + Get-HVvCenterServer + + .EXAMPLE + Get-HVvCenterServer -Name 'vCenter1' + + .OUTPUTS + Returns array of object type VMware.Hv.VirtualCenterInfo + + .NOTES + Author : Matt Frey. + Author email : mfrey@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.7 + PowerCLI Version : PowerCLI 11.2.0 + PowerShell Version : 5.1 + #> + + param( + [Parameter(Mandatory = $false)] + $HvServer = $null, + + [Parameter(Mandatory = $false)] + [string]$Name = $null + ) + + begin { + $services = Get-ViewAPIService -hvServer $hvServer + + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + } + + process { + + if ($null -ne $PSBoundParameters.Name) { + $vCenterList = $services.VirtualCenter.VirtualCenter_List() | Where-Object {$_.ServerSpec.ServerName -eq $Name} + } else { + $vCenterList = $services.VirtualCenter.VirtualCenter_List() + } + + } + + end { + + return $vCenterList + + } +} + +function Get-HVvCenterServerHealth { + <# + .Synopsis + Gets a the health info for a given vCenter Server. + + .DESCRIPTION + Queries and returns the VirtualCenterHealthInfo specified HVServer. + + .PARAMETER HvServer + Reference to Horizon View Server to query the virtual machines from. If the value is not passed or null then + first element from global:DefaultHVServers would be considered inplace of hvServer + + .PARAMETER VirtualCenter + A parameter to specify which vCenter Server to check health for. If not specified, this function will return the + health info for all vCenter Servers. + + .EXAMPLE + Get-HVvCenterServerHealth -VirtualCenter 'vCenter1' + + .EXAMPLE + Get-HVvCenterServerHealth -VirtualCenter $vCenter1 + + .EXAMPLE + Get-HVvCenterServerHealth + + .OUTPUTS + Returns array of object type VMware.Hv.VirtualCenterInfo + + .NOTES + Author : Matt Frey. + Author email : mfrey@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.7 + PowerCLI Version : PowerCLI 11.2.0 + PowerShell Version : 5.1 + #> + + param( + [Parameter(Mandatory = $false)] + $HvServer = $null, + + [Parameter(Mandatory = $false)] + $VirtualCenter = $null + ) + + begin { + $services = Get-ViewAPIService -hvServer $hvServer + + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + } + + process { + + if ($null -eq $PSBoundParameters.VirtualCenter) { + $VirtualCenterHealth = $services.VirtualCenterHealth.VirtualCenterHealth_List() + } else { + $objType = $VirtualCenter.getType() | Select-Object -ExpandProperty Name + Switch ($objType) { + 'String' { + $VirtualCenterHealth = $services.VirtualCenterHealth.VirtualCenterHealth_Get($(Get-HVvCenterServer -Name $VirtualCenter | Select-Object -ExpandProperty Id)) + } + 'VirtualCenterInfo' { + $VirtualCenterHealth = $services.VirtualCenterHealth.VirtualCenterHealth_Get($($VirtualCenter | Select-Object -ExpandProperty Id)) + } + 'VirtualCenterId' { + $VirtualCenterHealth = $services.VirtualCenterHealth.VirtualCenterHealth_Get($VirtualCenter) + } + } + } + + } + + end { + + return $VirtualCenterHealth + + } +} + function Get-JsonObject { param( [Parameter(Mandatory = $true)] @@ -462,8 +615,6 @@ function Add-HVRDSServer { } } - - function Connect-HVEvent { <# .SYNOPSIS @@ -1004,8 +1155,7 @@ function Get-HVFarm { if (! $farmList) { if (! $SuppressInfo) { Write-Host "Get-HVFarm: No Farm Found with given search parameters" - } - return $farmList + } } $farm_service_helper = New-Object VMware.Hv.FarmService $queryResults = @() @@ -1906,7 +2056,7 @@ function New-HVFarm { Set to true to enable provision of RDSServers immediately in farm. Applicable to Linked Clone and Instant Clone farms. -.PARAMETER StopOnProvisioningError +.PARAMETER StopProvisioningOnError Set to true to stop provisioning of all RDSServers on error. Applicable to Linked Clone and Instant Clone farms. @@ -1979,11 +2129,11 @@ function New-HVFarm { Reference to Horizon View Server to query the farms from. If the value is not passed or null then first element from global:DefaultHVServers would be considered in-place of hvServer. .EXAMPLE - New-HVFarm -LinkedClone -FarmName 'LCFarmTest' -ParentVM 'Win_Server_2012_R2' -SnapshotVM 'Snap_RDS' -VmFolder 'PoolVM' -HostOrCluster 'cls' -ResourcePool 'cls' -Datastores 'datastore1 (5)' -FarmDisplayName 'LC Farm Test' -Description 'created LC Farm from PS' -EnableProvisioning $true -StopOnProvisioningError $false -NamingPattern "LCFarmVM_PS" -MinReady 1 -MaximumCount 1 -SysPrepName "RDSH_Cust2" -NetBiosName "adviewdev" + New-HVFarm -LinkedClone -FarmName 'LCFarmTest' -ParentVM 'Win_Server_2012_R2' -SnapshotVM 'Snap_RDS' -VmFolder 'PoolVM' -HostOrCluster 'cls' -ResourcePool 'cls' -Datastores 'datastore1 (5)' -FarmDisplayName 'LC Farm Test' -Description 'created LC Farm from PS' -EnableProvisioning $true -StopProvisioningOnError $false -NamingPattern "LCFarmVM_PS" -MinReady 1 -MaximumCount 1 -SysPrepName "RDSH_Cust2" -NetBiosName "adviewdev" Creates new linkedClone farm by using naming pattern .EXAMPLE - New-HVFarm -InstantClone -FarmName 'ICFarmCL' -ParentVM 'vm-rdsh-ic' -SnapshotVM 'Snap_5' -VmFolder 'Instant_Clone_VMs' -HostOrCluster 'vimal-cluster' -ResourcePool 'vimal-cluster' -Datastores 'datastore1' -FarmDisplayName 'IC Farm using CL' -Description 'created IC Farm from PS command-line' -EnableProvisioning $true -StopOnProvisioningError $false -NamingPattern "ICFarmCL-" -NetBiosName "ad-vimalg" + New-HVFarm -InstantClone -FarmName 'ICFarmCL' -ParentVM 'vm-rdsh-ic' -SnapshotVM 'Snap_5' -VmFolder 'Instant_Clone_VMs' -HostOrCluster 'vimal-cluster' -ResourcePool 'vimal-cluster' -Datastores 'datastore1' -FarmDisplayName 'IC Farm using CL' -Description 'created IC Farm from PS command-line' -EnableProvisioning $true -StopProvisioningOnError $false -NamingPattern "ICFarmCL-" -NetBiosName "ad-vimalg" Creates new linkedClone farm by using naming pattern .EXAMPLE @@ -2193,11 +2343,11 @@ function New-HVFarm { [boolean] $EnableProvisioning = $true, - #farmSpec.automatedfarmSpec.virtualCenterProvisioningSettings.stopOnProvisioningError if LINKED_CLONE, INSTANT_CLONE + #farmSpec.automatedfarmSpec.virtualCenterProvisioningSettings.stopProvisioningOnError if LINKED_CLONE, INSTANT_CLONE [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] [boolean] - $StopOnProvisioningError = $true, + $StopProvisioningOnError = $true, [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] @@ -2790,7 +2940,6 @@ function Test-HVFarmSpec { } } - function Get-HVFarmProvisioningData { param( [Parameter(Mandatory = $false)] @@ -2865,7 +3014,6 @@ function Get-HVFarmProvisioningData { return $vmObject } - function Get-HVFarmStorageObject { param( @@ -2933,7 +3081,6 @@ function Get-HVFarmStorageObject { return $storageObject } - function Get-HVFarmNetworkSetting { param( [Parameter(Mandatory = $false)] @@ -2945,7 +3092,6 @@ function Get-HVFarmNetworkSetting { return $networkObject } - function Get-HVFarmCustomizationSetting { param( [Parameter(Mandatory = $false)] @@ -3078,7 +3224,6 @@ function Get-FarmSpec { return $farm_spec_helper.getDataObject() } - function New-HVPool { <# .Synopsis @@ -3302,7 +3447,7 @@ function New-HVPool { .PARAMETER BlackoutTimes A list of blackout times. -.PARAMETER StopOnProvisioningError +.PARAMETER StopProvisioningOnError Set to true to stop provisioning of all VMs on error. Applicable to Full, Linked, Instant Clone Pools. @@ -3429,7 +3574,7 @@ function New-HVPool { first element from global:DefaultHVServers would be considered in-place of hvServer. .EXAMPLE - C:\PS>New-HVPool -LinkedClone -PoolName 'vmwarepool' -UserAssignment FLOATING -ParentVM 'Agent_vmware' -SnapshotVM 'kb-hotfix' -VmFolder 'vmware' -HostOrCluster 'CS-1' -ResourcePool 'CS-1' -Datastores 'datastore1' -NamingMethod PATTERN -PoolDisplayName 'vmware linkedclone pool' -Description 'created linkedclone pool from ps' -EnableProvisioning $true -StopOnProvisioningError $false -NamingPattern "vmware2" -MinReady 0 -MaximumCount 1 -SpareCount 1 -ProvisioningTime UP_FRONT -SysPrepName vmwarecust -CustType SYS_PREP -NetBiosName adviewdev -DomainAdmin root + C:\PS>New-HVPool -LinkedClone -PoolName 'vmwarepool' -UserAssignment FLOATING -ParentVM 'Agent_vmware' -SnapshotVM 'kb-hotfix' -VmFolder 'vmware' -HostOrCluster 'CS-1' -ResourcePool 'CS-1' -Datastores 'datastore1' -NamingMethod PATTERN -PoolDisplayName 'vmware linkedclone pool' -Description 'created linkedclone pool from ps' -EnableProvisioning $true -StopProvisioningOnError $false -NamingPattern "vmware2" -MinReady 0 -MaximumCount 1 -SpareCount 1 -ProvisioningTime UP_FRONT -SysPrepName vmwarecust -CustType SYS_PREP -NetBiosName adviewdev -DomainAdmin root Create new automated linked clone pool with naming method pattern .EXAMPLE @@ -3667,13 +3812,19 @@ function New-HVPool { # flashSettings #desktopSpec.desktopSettings.flashSettings.quality [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] + [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] + [Parameter(Mandatory = $false,ParameterSetName = 'FULL_CLONE')] + [Parameter(Mandatory = $false,ParameterSetName = 'MANUAL')] [ValidateSet('NO_CONTROL', 'LOW', 'MEDIUM', 'HIGH')] - [string]$quality = 'NO_CONTROL', + [string]$Quality = 'NO_CONTROL', #desktopSpec.desktopSettings.flashSettings.throttling [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] + [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] + [Parameter(Mandatory = $false,ParameterSetName = 'FULL_CLONE')] + [Parameter(Mandatory = $false,ParameterSetName = 'MANUAL')] [ValidateSet('DISABLED', 'CONSERVATIVE', 'MODERATE', 'AGGRESSIVE')] - [string]$throttling = 'DISABLED', + [string]$Throttling = 'DISABLED', #mirageConfigurationOverrides #desktopSpec.desktopSettings.mirageConfigurationOverrides.overrideGlobalSetting @@ -3878,12 +4029,12 @@ function New-HVPool { [boolean] $EnableProvisioning = $true, - #desktopSpec.automatedDesktopSpec.virtualCenterProvisioningSettings.stopOnProvisioningError if LINKED_CLONE, INSTANT_CLONE, FULL_CLONE + #desktopSpec.automatedDesktopSpec.virtualCenterProvisioningSettings.stopProvisioningOnError if LINKED_CLONE, INSTANT_CLONE, FULL_CLONE [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] [Parameter(Mandatory = $false,ParameterSetName = 'FULL_CLONE')] [boolean] - $StopOnProvisioningError = $true, + $StopProvisioningOnError = $true, [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] @@ -4158,6 +4309,7 @@ function New-HVPool { $adContainer = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.AdContainer } $custType = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.CustomizationType + $reusePreExistingAccounts = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.reusePreExistingAccounts if ($jsonObject.AutomatedDesktopSpec.ProvisioningType -eq "INSTANT_CLONE_ENGINE") { $InstantClone = $true if ($null -ne $jsonObject.AutomatedDesktopSpec.CustomizationSettings.CloneprepCustomizationSettings) { @@ -4178,7 +4330,6 @@ function New-HVPool { 'SYS_PREP' { $sysprepCustomizationSettings = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.SysprepCustomizationSettings $sysPrepName = $sysprepCustomizationSettings.customizationSpec - $reusePreExistingAccounts = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.reusePreExistingAccounts } 'QUICK_PREP' { $powerOffScriptName = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.QuickprepCustomizationSettings.PowerOffScriptName @@ -4922,7 +5073,6 @@ function Get-HVPoolProvisioningData { return $vmObject } - function Get-HVHostOrClusterID { <# .Synopsis @@ -5250,7 +5400,7 @@ function Get-HVPoolCustomizationSetting { } if ($null -eq $ViewComposerDomainAdministratorID) { throw "No Composer Domain Administrator found with netBiosName: [$netBiosName]" - } + } if ($custType -eq 'SYS_PREP') { $desktopSpecObj.AutomatedDesktopSpec.CustomizationSettings.CustomizationType = 'SYS_PREP' $desktopSpecObj.AutomatedDesktopSpec.CustomizationSettings.SysprepCustomizationSettings = Get-CustomizationObject @@ -5274,6 +5424,7 @@ function Get-HVPoolCustomizationSetting { throw "The customization type: [$custType] is not supported for LinkedClone Pool" } $desktopSpecObj.AutomatedDesktopSpec.CustomizationSettings.DomainAdministrator = $ViewComposerDomainAdministratorID + $desktopSpecObj.AutomatedDesktopSpec.CustomizationSettings.ReusePreExistingAccounts = $reusePreExistingAccounts } elseIf ($FullClone) { if ($custType -eq 'SYS_PREP') { $desktopSpecObj.AutomatedDesktopSpec.CustomizationSettings.CustomizationType = 'SYS_PREP' @@ -6902,6 +7053,239 @@ function Get-Machine ($Pool,$MachineList) { return $machines } +function Get-HVBaseImageVM { + <# + .Synopsis + Gets a list of compatible base image virtual machines. + + .DESCRIPTION + Queries and returns BaseImageVmInfo for the specified vCenter Server. + + .PARAMETER HvServer + Reference to Horizon View Server to query the virtual machines from. If the value is not passed or null then + first element from global:DefaultHVServers would be considered in place of hvServer. + + .PARAMETER VirtualCenter + A parameter to specify which vCenter Server to check base image VMs for. It can be specified as a String, + containing the name of the vCenter, or as a vCenter object as returned by Get-HVvCenterServer. If the value is + not passed or null then first element returned from Get-HVvCenterServer would be considered in place of VirtualCenter. + + .PARAMETER Type + A parameter to define the type of compatability to check the base image VM list against. Valid options are 'VDI', 'RDS', or 'ALL' + 'VDI' will return all desktop compatible Base Image VMs. + 'RDS' will return all RDSH compatible Base Image VMs. + 'ALL' will return all Base Image VMs, regardless of compatibility. + The default value is 'ALL'. + + .PARAMETER Name + The name of a virtual machine (if known), to filter Base Image VMs on. Wildcards are accepted. If Name is specified, then Type + is not considered for filtering. + + .EXAMPLE + Get-HVBaseImageVM -VirtualCenter 'vCenter1' -Type VDI + + .EXAMPLE + Get-HVBaseImageVM -VirtualCenter $vCenter1 -Type ALL + + .EXAMPLE + Get-HVBaseImageVM -Name '*WIN10*' + + .OUTPUTS + Returns array of object type VMware.Hv.BaseImageVmInfo + + .NOTES + Author : Matt Frey. + Author email : mfrey@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.7 + PowerCLI Version : PowerCLI 11.2.0 + PowerShell Version : 5.1 + #> + + [cmdletbinding( + DefaultParameterSetName='Type' + )] + + param( + [Parameter(Mandatory = $false)] + $HvServer = $null, + + [Parameter(Mandatory = $false)] + $VirtualCenter = $null, + + [Parameter(Mandatory = $false,ParameterSetName = 'Type')] + [ValidateSet('VDI','RDS','ALL')] + $Type = 'VDI', + + [Parameter(Mandatory = $false,ParameterSetName = 'Name')] + [string]$Name = $null + ) + + begin { + $services = Get-ViewAPIService -hvServer $hvServer + + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + + if ($null -eq $PSBoundParameters.VirtualCenter) { + $VirtualCenterId = Get-HVvCenterServer | Select-Object -First 1 -ExpandProperty Id + } else { + $objType = $VirtualCenter.getType() | Select-Object -ExpandProperty Name + Switch ($objType) { + 'String' { + $VirtualCenterId = Get-HVvCenterServer -Name $VirtualCenter | Select-Object -ExpandProperty Id + } + 'VirtualCenterInfo' { + $VirtualCenterId = $VirtualCenter | Select-Object -ExpandProperty Id + } + 'VirtualCenterId' { + $VirtualCenterId = $VirtualCenter + } + } + } + + } + + process { + + $BaseImageVMList = $services.BaseImageVM.BaseImageVM_List($VirtualCenterId) + + #For all conditions, see https://vdc-download.vmware.com/vmwb-repository/dcr-public/3721109b-48a5-4ffb-a0ad-6d6a44f2f288/ff45dfca-1050-4265-93ef-4e7d702322e4/vdi.utils.virtualcenter.BaseImageVm.BaseImageVmIncompatibleReasons.html + + If ($null -ne $PSBoundParameters.Name) { + $CompatibleBaseImageVMs = $BaseImageVMList | Where-Object {$_.Name -like $Name} + } Else { + Switch ($Type) { + + 'VDI' { + $CompatibleBaseImageVMs = $BaseImageVMList | Where-Object { + ($_.IncompatibleReasons.InUseByDesktop -eq $false) -and + ($_.IncompatibleReasons.InUseByLinkedCloneDesktop -eq $false) -and + ($_.IncompatibleReasons.ViewComposerReplica -eq $false) -and + ($_.IncompatibleReasons.UnsupportedOS -eq $false) -and + ($_.IncompatibleReasons.NoSnapshots -eq $false) -and + (($null -eq $_.IncompatibleReasons.InstantInternal) -or ($_.IncompatibleReasons.InstantInternal -eq $false)) + } + } + 'RDS' { + $CompatibleBaseImageVMs = $BaseImageVMList | Where-Object { + ($_.IncompatibleReasons.InUseByDesktop -eq $false) -and + ($_.IncompatibleReasons.InUseByLinkedCloneDesktop -eq $false) -and + ($_.IncompatibleReasons.ViewComposerReplica -eq $false) -and + ($_.IncompatibleReasons.UnsupportedOSForLinkedCloneFarm -eq $false) -and + ($_.IncompatibleReasons.NoSnapshots -eq $false) -and + (($null -eq $_.IncompatibleReasons.InstantInternal) -or ($_.IncompatibleReasons.InstantInternal -eq $false)) + } + } + 'ALL' { + $CompatibleBaseImageVMs = $BaseImageVMList + } + + } + } + + } + + end { + + return $CompatibleBaseImageVMs + + } +} + +function Get-HVBaseImageSnapshot { + <# + .Synopsis + Gets a list of compatible base image virtual machines. + + .DESCRIPTION + Queries and returns BaseImageVmInfo for the specified vCenter Server. + + .PARAMETER HvServer + Reference to Horizon View Server to query the virtual machines from. If the value is not passed or null then + first element from global:DefaultHVServers would be considered in place of hvServer. + + .PARAMETER BaseImageVM + The BaseImageVM to query snapshots for. This parameter is required. Wildcards are accepted. This parameter also supports + pipeline operations with Get-HVBaseImageVM + + .EXAMPLE + Get-HVBaseImageSnapshots -BaseImageVM 'WIN10-BaseImage' + + .EXAMPLE + Get-HVBaseImageSnapshots -BaseImageVM '*WIN10*' + + .EXAMPLE + Get-HVBaseImageVM -Name 'WIN10-BaseImage' | Get-HVBaseImageSnapshots + + .OUTPUTS + Array of object type VMware.Hv.BaseImageSnapshotInfo + + .NOTES + Author : Matt Frey. + Author email : mfrey@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.7 + PowerCLI Version : PowerCLI 11.2.0 + PowerShell Version : 5.1 + #> + + [cmdletbinding( + DefaultParameterSetName='Type' + )] + + param( + [Parameter(Mandatory = $false)] + $HvServer = $null, + + [Parameter(Mandatory = $true,ValueFromPipeLine=$true)] + $BaseImageVM = $null + ) + + begin { + $services = Get-ViewAPIService -hvServer $hvServer + + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + + } + + process { + + if ($null -ne $PSBoundParameters.BaseImageVM) { + $objType = $BaseImageVM.getType() | Select-Object -ExpandProperty Name + Switch ($objType) { + 'String' { + $BaseImageVMObj = Get-HVBaseImageVM -Name $BaseImageVM + } + 'BaseImageVMInfo' { + $BaseImageVMObj = $BaseImageVM + } + 'Object[]' { + Write-Error 'This function cannot accept an array of Base Image VMs. You must specify only a single Base Image VM.' + Break + } + } + $BaseImageSnapshotList = $services.BaseImageSnapshot.BaseImageSnapshot_List($BaseImageVMObj.Id) + } + + } + + end { + + return $BaseImageSnapshotList + + } +} + function Set-HVPoolSpec { param( [Parameter(Mandatory = $true)] @@ -11562,12 +11946,542 @@ function Set-HVInstantCloneMaintenance { [System.gc]::collect() } } + +Function Get-HVApplication { +<# +.Synopsis + Gets the application information. + +.DESCRIPTION + Gets the application information. This will be useful to find out whether the specified application exists or not. If the application name is not specified, this will lists all the applications in the Pod. + +.PARAMETER ApplicationName + Name of the application. + +.PARAMETER HvServer + View API service object of Connect-HVServer cmdlet. + +.PARAMETER FormatList + Displays the list of the available applications in Table Format if this parameter is set to True. + +.EXAMPLE + Get-HVApplication -ApplicationName 'App1' -HvServer $HvServer + Queries and returns 'App1' information. + +.EXAMPLE + Get-HVApplication -HvServer $HvServer -FormatList:$True + Lists all the applications in the Pod. + +.OUTPUTS + Returns the information of the specified application if it specified, else displays all the available applications. + +.NOTES + Author : Samiullasha S + Author email : ssami@vmware.com + Version : 1.2 + + ===Tested Against Environment==== + Horizon View Server Version : 7.8.0 + PowerCLI Version : PowerCLI 11.1 + PowerShell Version : 5.0 +#> + param ( + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [string]$ApplicationName = $Null, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + $HvServer = $Null, + + [Parameter(Mandatory = $False)] + [string]$FormatList = $False + ) + begin { + $services = Get-ViewAPIService -HvServer $HvServer + if ($null -eq $services) { + Write-Error "Could not retrieve View API services from connection object." + break + } + } + process { + if ($ApplicationName) { + $eqFilter = Get-HVQueryFilter 'data.name' -Eq $ApplicationName + $ResourceObjs = Get-HVQueryResult -EntityType ApplicationInfo -Filter $eqFilter -HvServer $HvServer + if(!$ResourceObjs){Write-host "No application found with specified name: $ApplicationName"; return} + Write-host "Application found with specified name: $ApplicationName" + return $ResourceObjs + } + $ResourceObjs = Get-HVQueryResult -EntityType ApplicationInfo -HvServer $HvServer + if ($FormatList -eq $True){ return $ResourceObjs.data | Format-Table -AutoSize} + return $ResourceObjs.data + } + end { + [System.GC]::Collect() + } +} + +Function Remove-HVApplication { +<# +.Synopsis + Removes the specified application if exists. + +.DESCRIPTION + Removes the specified application if exists. + +.PARAMETER ApplicationName + Application to be deleted. + The name of the application must be given that is to be searched for and remove if exists. + +.PARAMETER HvServer + View API service object of Connect-HVServer cmdlet. + +.EXAMPLE + Remove-HVApplication -ApplicationName 'App1' -HvServer $HvServer + Removes 'App1', if exists. + +.OUTPUTS + Removes the specified application if exists. + +.NOTES + Author : Samiullasha S + Author email : ssami@vmware.com + Version : 1.2 + + ===Tested Against Environment==== + Horizon View Server Version : 7.8.0 + PowerCLI Version : PowerCLI 11.1 + PowerShell Version : 5.0 +#> + param ( + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [string]$ApplicationName, + + [Parameter(Mandatory = $False)] + $HvServer = $null + ) + begin { + $services = Get-ViewAPIService -HvServer $HvServer + if ($null -eq $services) { + Write-Error "Could not retrieve View API services from connection object" + break + } + } + process { + $App= Get-HVApplication -ApplicationName $ApplicationName -HvServer $HvServer + if (!$App) { + Write-Host "Application '$ApplicationName' not found. $_" + return + } + $AppService= New-Object VMware.Hv.ApplicationService + $AppService.Application_Delete($services,$App.Id) + if ($?) { + Write-Host "'$ApplicationName' has been successfully removed." + } + } + end { + [System.GC]::Collect() + } +} + +Function New-HVManualApplication { +<# +.Synopsis + Creates a Manual Application. + +.DESCRIPTION + Creates Application manually with given parameters. + +.PARAMETER HvServer + View API service object of Connect-HVServer cmdlet. + +.PARAMETER Name + The Application name is the unique identifier used to identify this Application. + +.PARAMETER DisplayName + The display name is the name that users will see when they connect to view client. If the display name is left blank, it defaults to Name. + +.PARAMETER Description + The description is a set of notes about the Application. + +.PARAMETER ExecutablePath + Path to Application executable. + +.PARAMETER Version + Application version. + +.PARAMETER Publisher + Application publisher. + +.PARAMETER Enabled + Indicates if Application is enabled. + +.PARAMETER EnablePreLaunch + Application can be pre-launched if value is true. + +.PARAMETER ConnectionServerRestrictions + Connection server restrictions. This is a list of tags that access to the application is restricted to. Empty/Null list means that the application can be accessed from any connection server. + +.PARAMETER CategoryFolderName + Name of the category folder in the user's OS containing a shortcut to the application. Unset if the application does not belong to a category. + +.PARAMETER ClientRestrictions + Client restrictions to be applied to Application. Currently it is valid for RDSH pools. + +.PARAMETER ShortcutLocations + Locations of the category folder in the user's OS containing a shortcut to the desktop. The value must be set if categoryFolderName is provided. + +.PARAMETER MultiSessionMode + Multi-session mode for the application. An application launched in multi-session mode does not support reconnect behavior when user logs in from a different client instance. + +.PARAMETER MaxMultiSessions + Maximum number of multi-sessions a user can have in this application pool. + +.PARAMETER StartFolder + Starting folder for Application. + +.PARAMETER Args + Parameters to pass to application when launching. + +.PARAMETER Farm + Farm name. + +.PARAMETER AutoUpdateFileTypes + Whether or not the file types supported by this application should be allowed to automatically update to reflect changes reported by the agent. + +.PARAMETER AutoUpdateOtherFileTypes + Whether or not the other file types supported by this application should be allowed to automatically update to reflect changes reported by the agent. + +.EXAMPLE + New-HVManualApplication -Name 'App1' -DisplayName 'DisplayName' -Description 'ApplicationDescription' -ExecutablePath "PathOfTheExecutable" -Version 'AppVersion' -Publisher 'PublisherName' -Farm 'FarmName' + Creates a manual application App1 in the farm specified. + +.OUTPUTS + A success message is displayed when done. + +.NOTES + Author : Samiullasha S + Author email : ssami@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.8.0 + PowerCLI Version : PowerCLI 11.1 + PowerShell Version : 5.0 +#> + param ( + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [VMware.VimAutomation.HorizonView.Impl.V1.ViewServerImpl]$HvServer, + + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [string][ValidateLength(1,64)]$Name, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String][ValidateLength(1,256)]$DisplayName = $Name, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String][ValidateLength(1,1024)]$Description, + + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [String]$ExecutablePath, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String]$Version, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String]$Publisher, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$Enabled = $True, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$EnablePreLaunch=$False, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [string[]]$ConnectionServerRestrictions, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True, ParameterSetName = 'categoryFolderName')] + [String][ValidateRange(1,64)]$CategoryFolderName, + + #Below Parameter is for Client restrictions to be applied to Application. Currently it is valid for RDSH pools. + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$clientRestrictions = $False, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True, ParameterSetName = 'categoryFolderName')] + [String[]]$ShortcutLocations, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [ValidateSet('DISABLED','ENABLED_DEFAULT_OFF','ENABLED_DEFAULT_ON','ENABLED_ENFORCED')] + [String]$MultiSessionMode = 'DISABLED', + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [ValidateScript({if(($MultiSessionMode -eq 'ENABLED_DEFAULT_OFF') -or ($MultiSessionMode -eq 'ENABLED_DEFAULT_ON') -or ($MultiSessionMode -eq 'ENABLED_ENFORCED')){$_ -eq 1}})] + [Int]$MaxMultiSessions, + + #Below parameters are for ExecutionData, moved ExecutablePath, Version and Publisher to above from this. + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String]$StartFolder, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String]$Args, + + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [String]$Farm, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$AutoUpdateFileTypes = $True, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$AutoUpdateOtherFileTypes = $True + ) + begin { + $services = Get-ViewAPIService -HvServer $HvServer + if ($null -eq $services) { + Write-Error "Could not retrieve View API services from connection object" + break + } + $FarmInfo = Get-HVFarm -FarmName $Farm + if ($null -eq $FarmInfo) { + Write-Error "Could not find the specified Farm." + break + } + } + process { + $App = Get-HVApplication -ApplicationName $Name -HvServer $HvServer + if ($App) { + Write-Host "Application already exists with the name : $Name" + return + } + $AppData = New-Object VMware.Hv.ApplicationData -Property @{ 'Name' = $Name; 'DisplayName' = $DisplayName; 'Description' = $Description; 'Enabled' = $Enabled; 'EnableAntiAffinityRules' = $EnableAntiAffinityRules; 'AntiAffinityPatterns' = $AntiAffinityPatterns; 'AntiAffinityCount' = $AntiAffinityCount; 'EnablePreLaunch' = $EnablePreLaunch; 'multiSessionMode' = $MultiSessionMode; 'maxMultiSessions' = $MaxMultiSessions; 'ConnectionServerRestrictions' = $ConnectionServerRestrictions; 'CategoryFolderName' = $CategoryFolderName; 'ClientRestrictions' = $ClientRestrictions; 'ShortcutLocations' = $ShortcutLocations} + $ExecutionData = New-object VMware.Hv.ApplicationExecutionData -Property @{ 'ExecutablePath' = $ExecutablePath; 'Version' = $Version; 'Publisher' = $Publisher; 'StartFolder' = $StartFolder; 'Args' = $Args; 'Farm' = $FarmInfo.id; 'AutoUpdateFileTypes' = $AutoUpdateFileTypes; 'AutoUpdateOtherFileTypes' = $AutoUpdateOtherFileTypes} + $AppSpec = New-Object VMware.Hv.ApplicationSpec -Property @{ 'Data' = $AppData; 'ExecutionData' = $ExecutionData} + $AppService = New-Object VMware.Hv.ApplicationService + $AppService.Application_Create($services,$AppSpec) + if ($?) { + Write-Host "Application '$Name' created successfully" + return + } + Write-Host "Application creation of '$Name' has failed. $_" + } + end { + [System.GC]::Collect() + } +} + +Function Get-HVPreInstalledApplication { +<# +.Synopsis + Gets the list of Pre-installed Applications from the RDS Server(s). + +.DESCRIPTION + Gets the list of Pre-installed Applications from the RDS Server(s). + +.PARAMETER FarmName + Name of the Farm on which to discover installed applications. + +.PARAMETER HvServer + View API service object of Connect-HVServer cmdlet. + +.EXAMPLE + Get-HVPreInstalledApplication -FarmName 'Farm1' -HvServer $HvServer + Gets the list of Applications present in 'Farm1', if exists. + +.OUTPUTS + Gets the list of Applications from the specified Farm if exists. + +.NOTES + Author : Samiullasha S + Author email : ssami@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.8.0 + PowerCLI Version : PowerCLI 11.1 + PowerShell Version : 5.0 +#> + param ( + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [String][ValidateLength(1,64)]$FarmName, + + [Parameter(Mandatory = $False)] + $HvServer = $null + ) + begin { + $services = Get-ViewAPIService -HvServer $HvServer + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + $Farm = Get-HVFarm -FarmName $FarmName + if($null -eq $Farm) { + Write-Error "Could not find the specified Farm." + break + } + } + process { + $FarmService = New-Object VMware.Hv.FarmService + $Data = $FarmService.Farm_DiscoverInstalledApplications($services,$Farm.Id) + return $Data + } + end { + [System.GC]::Collect() + } +} + +Function New-HVPreInstalledApplication { +<# +.Synopsis + Creates a application pool from Pre-installed applications on RDS Server(s). + +.DESCRIPTION + Creates a application pool from Pre-installed applications on RDS Server(s). + +.PARAMETER HvServer + View API service object of Connect-HVServer cmdlet. + +.PARAMETER ApplicationName + The Application name is the unique identifier used to identify this Application. + +.PARAMETER DisplayName + The display name is the name that users will see when they connect to view client. If the display name is left blank, it defaults to Name. + +.PARAMETER FarmName + Farm name. + +.PARAMETER EnablePreLaunch + Application can be pre-launched if value is true. + +.PARAMETER ConnectionServerRestrictions + Connection server restrictions. This is a list of tags that access to the application is restricted to. Empty/Null list means that the application can be accessed from any connection server. + +.PARAMETER CategoryFolderName + Name of the category folder in the user's OS containing a shortcut to the application. Unset if the application does not belong to a category. + +.PARAMETER ClientRestrictions + Client restrictions to be applied to Application. Currently it is valid for RDSH pools. + +.EXAMPLE + New-HVPreInstalledApplication -ApplicationName 'App1' -DisplayName 'DisplayName' -FarmName 'FarmName' + Creates a application App1 from the farm specified. + +.EXAMPLE + New-HVPreInstalledApplication -ApplicationName 'App2' -FarmName FarmManual -EnablePreLaunch $True + Creates a application App2 from the farm specified and the PreLaunch option will be enabled. + +.OUTPUTS + A success message is displayed when done. + +.NOTES + Author : Samiullasha S + Author email : ssami@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.8.0 + PowerCLI Version : PowerCLI 11.1 + PowerShell Version : 5.0 +#> + param ( + [Parameter(Mandatory = $False)] + $HvServer = $null, + + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [string][ValidateLength(1,64)]$ApplicationName, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String][ValidateLength(1,256)]$DisplayName = $ApplicationName, + + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [String][ValidateLength(1,64)]$FarmName, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$EnablePreLaunch=$False, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [string[]]$ConnectionServerRestrictions, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True,ParameterSetName = 'categoryFolderName')] + [String][ValidateRange(1,64)]$CategoryFolderName, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$clientRestrictions = $False + ) + begin { + $services = Get-ViewAPIService -HvServer $HvServer + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + $FarmInfo = Get-HVFarm -FarmName $FarmName + if($null -eq $FarmInfo) { + Write-Error "Could not find the specified Farm $FarmName." + break + } + } + process { + #Validate the Application name uniqueness with existing applications. + $ResourceObjs = Get-HVApplication -HvServer $HvServer + foreach($App in ($ResourceObjs.name)) { + if($App -eq $ApplicationName) { + Write-Host "$ApplicationName already exists in the Application Pool." + return + } + } + #Validate the application name uniqueness with Desktops. + $DesktopSummary = Get-HVQueryResult -EntityType DesktopSummaryView -HvServer $hvserver + foreach($App in $DesktopSummary) { + if($App.DesktopSummaryData.Name -eq $ApplicationName) { + Write-Host "$ApplicationName already exists in the Desktop Pool." + return + } + } + #get all the applications installed in RDS Server(s). + $AppsInRDS = Get-HVPreinstalledApplication -FarmName $FarmName + $AppFoundInRDS = $False + foreach($App in ($AppsInRDS)) { + if($($App.name) -eq ($ApplicationName)) { + $AppFoundInRDS = $True + $ApplicationID = $ApplicationName -replace " ","_" + $ApplicationData = New-Object VMware.Hv.ApplicationData -Property @{ 'Name' = $ApplicationID; + 'DisplayName' = $DisplayName; + 'EnablePreLaunch' = $EnablePreLaunch; + 'ConnectionServerRestrictions' = $ConnectionServerRestrictions; + 'CategoryFolderName' = $CategoryFolderName; + 'ClientRestrictions' = $ClientRestrictions } + $ExecutionData = New-object VMware.Hv.ApplicationExecutionData -Property @{ 'ExecutablePath' = $App.ExecutionData.ExecutablePath; + 'Version' = $App.ExecutionData.Version; + 'Publisher' = $App.ExecutionData.Publisher; + 'Args' = $App.ExecutionData.Args; + 'StartFolder' = $App.ExecutionData.StartFolder; + 'Farm' = $FarmInfo.Id; + 'AutoUpdateFileTypes' = $App.ExecutionData.AutoUpdateFileTypes; + 'AutoUpdateOtherFileTypes' = $App.executionData.AutoUpdateOtherFileTypes } + $ApplicationSpec = New-Object VMware.Hv.ApplicationSpec -Property @{ 'Data' = $ApplicationData; 'ExecutionData' = $ExecutionData} + $AppService = New-Object VMware.Hv.ApplicationService + $AppService.Application_Create($services,$ApplicationSpec) + if($?) { + Write-Host "Application '$ApplicationName' created successfully" + return + } + Write-Host "Failed to create Application '$ApplicationName'. $_ " + return + } + } + if ($AppFoundInRDS -eq $False) { + Write-Host ""$ApplicationName" does not exist in any of the RDS Server(s) belongs to the Farm $FarmName." + } + } + end { + [System.GC]::Collect() + } +} + # Object related Export-ModuleMember -Function Get-HVMachine, Get-HVMachineSummary, Get-HVQueryResult, Get-HVQueryFilter, Get-HVInternalName # RDS Farm related Export-ModuleMember -Function Get-HVFarmSummary, Start-HVFarm, Start-HVPool, New-HVFarm, Remove-HVFarm, Get-HVFarm, Set-HVFarm, Add-HVRDSServer # Desktop Pool related Export-ModuleMember -Function Get-HVPoolSummary, New-HVPool, Remove-HVPool, Get-HVPool, Set-HVPool, Get-HVPoolSpec, Add-HVDesktop +# Application Pool related +Export-ModuleMember -Function Get-HVApplication, Remove-HVApplication, New-HVManualApplication, Get-HVPreInstalledApplication, New-HVPreInstalledApplication # Entitlement related Export-ModuleMember -Function New-HVEntitlement,Get-HVEntitlement,Remove-HVEntitlement Export-ModuleMember -Function Set-HVMachine, Reset-HVMachine, Remove-HVMachine @@ -11579,5 +12493,7 @@ Export-ModuleMember -Function Get-HVGlobalSettings, Set-HVApplicationIcon, Remov Export-ModuleMember -Function Get-HVResourceStructure, Get-HVLocalSession, Get-HVGlobalSession # Event Database related Export-ModuleMember -Function Get-HVEventDatabase, Set-HVEventDatabase, Clear-HVEventDatabase, Get-HVEvent, Connect-HVEvent, Disconnect-HVEvent +# vCenter Server related +Export-ModuleMember -Function Get-HVvCenterServer, Get-HVvCenterServerHealth # Misc/other related -Export-ModuleMember -Function Get-HVlicense, Set-HVlicense, Get-HVHealth, Set-HVInstantCloneMaintenance \ No newline at end of file +Export-ModuleMember -Function Get-HVlicense, Set-HVlicense, Get-HVHealth, Set-HVInstantCloneMaintenance, Get-HVBaseImageVM, Get-HVBaseImageVMSnapshot diff --git a/Modules/VMware.VMC/VMware.VMC.psd1 b/Modules/VMware.VMC/VMware.VMC.psd1 index 105fec0..397ab8d 100755 Binary files a/Modules/VMware.VMC/VMware.VMC.psd1 and b/Modules/VMware.VMC/VMware.VMC.psd1 differ diff --git a/Modules/VMware.VMC/VMware.VMC.psm1 b/Modules/VMware.VMC/VMware.VMC.psm1 index 4fe807d..88eaa28 100644 --- a/Modules/VMware.VMC/VMware.VMC.psm1 +++ b/Modules/VMware.VMC/VMware.VMC.psm1 @@ -690,7 +690,7 @@ Function Get-VMCLogicalNetwork { Created by: Kyle Ruddy Date: 03/06/2018 Organization: VMware - Blog: https://thatcouldbeaproblem.com + Blog: https://www.kmruddy.com Twitter: @kmruddy =========================================================================== @@ -761,7 +761,7 @@ Function Remove-VMCLogicalNetwork { Created by: Kyle Ruddy Date: 03/06/2018 Organization: VMware - Blog: https://thatcouldbeaproblem.com + Blog: https://www.kmruddy.com Twitter: @kmruddy =========================================================================== @@ -808,7 +808,7 @@ Function New-VMCLogicalNetwork { Created by: Kyle Ruddy Date: 03/06/2018 Organization: VMware - Blog: https://thatcouldbeaproblem.com + Blog: https://www.kmruddy.com Twitter: @kmruddy =========================================================================== @@ -1418,11 +1418,205 @@ Twitter: @LucD22 } } } +Function New-VMCSDDCCluster { + <# + .NOTES + =========================================================================== + Created by: Kyle Ruddy + Date: 03/16/2019 + Organization: VMware + Blog: https://www.kmruddy.com + Twitter: @kmruddy + =========================================================================== + + .SYNOPSIS + Creates a new cluster for the designated SDDC + .DESCRIPTION + Creates a new cluster + .EXAMPLE + New-VMCSDDCCluster -OrgName -SDDCName -HostCount 1 -CPUCoreCount 8 + #> + [cmdletbinding(SupportsShouldProcess = $true,ConfirmImpact='High')] + param( + [Parameter(Mandatory=$true)][String]$OrgName, + [Parameter(Mandatory=$true)][String]$SDDCName, + [Parameter(Mandatory=$true)][Int]$HostCount, + [Parameter(Mandatory=$true)][ValidateSet("8","16","32")]$CPUCoreCount + ) + + if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } + + $orgId = Get-VMCOrg -Name $OrgName | Select-Object -ExpandProperty Id + $sddcId = Get-VMCSDDC -Name $SDDCName -Org $OrgName | Select-Object -ExpandProperty Id + + if(-not $orgId) { + Write-Host -ForegroundColor red "Unable to find Org $OrgName, please verify input" + break + } + if(-not $sddcId) { + Write-Host -ForegroundColor red "Unable to find SDDC $SDDCName, please verify input" + break + } + + $sddcClusterSvc = Get-VmcService -Name com.vmware.vmc.orgs.sddcs.clusters + + $sddcClusterCreateSpec = $sddcClusterSvc.Help.create.cluster_config.Create() + $sddcClusterCreateSpec.host_cpu_cores_count = $CPUCoreCount + $sddcClusterCreateSpec.num_hosts = $HostCount + + $sddcClusterTask = $sddcClusterSvc.Create($org.Id, $sddc.Id, $sddcClusterCreateSpec) + $sddcClusterTask | Select-Object Id,Task_Type,Status,Created | Format-Table +} +Function Get-VMCSDDCCluster { + <# + .NOTES + =========================================================================== + Created by: Kyle Ruddy + Date: 03/16/2019 + Organization: VMware + Blog: https://www.kmruddy.com + Twitter: @kmruddy + =========================================================================== + + .SYNOPSIS + Retreives cluster information for the designated SDDC + .DESCRIPTION + Lists cluster information for an SDDC + .EXAMPLE + Get-VMCSDDCCluster -OrgName -SDDCName -HostCount 1 -CPUCoreCount 8 + #> + [cmdletbinding(SupportsShouldProcess = $true,ConfirmImpact='Low')] + param( + [Parameter(Mandatory=$true)][String]$OrgName, + [Parameter(Mandatory=$true)][String]$SddcName + ) + + if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } + + $orgId = Get-VMCOrg -Name $OrgName | Select-Object -ExpandProperty Id + $sddcId = Get-VMCSDDC -Name $SDDCName -Org $OrgName | Select-Object -ExpandProperty Id + + if(-not $orgId) { + Write-Host -ForegroundColor red "Unable to find Org $OrgName, please verify input" + break + } + if(-not $sddcId) { + Write-Host -ForegroundColor red "Unable to find SDDC $SDDCName, please verify input" + break + } + + $clusterOutput = @() + $sddcClusters = Get-VMCSDDC -Org $OrgName -Name $SDDCName | Select-Object -ExpandProperty resource_config | Select-Object -ExpandProperty clusters + foreach ($c in $sddcClusters) { + $tempCluster = "" | Select-Object Id, Name, State + $tempCluster.Id = $c.cluster_id + $tempCluster.Name = $c.cluster_name + $tempCluster.State = $c.cluster_state + $clusterOutput += $tempCluster + } + return $clusterOutput +} +Function New-VMCSDDCCluster { + <# + .NOTES + =========================================================================== + Created by: Kyle Ruddy + Date: 03/16/2019 + Organization: VMware + Blog: https://www.kmruddy.com + Twitter: @kmruddy + =========================================================================== + + .SYNOPSIS + Creates a new cluster for the designated SDDC + .DESCRIPTION + Creates a new cluster + .EXAMPLE + New-VMCSDDCCluster -OrgName -SDDCName -HostCount 1 -CPUCoreCount 8 + #> + [cmdletbinding(SupportsShouldProcess = $true,ConfirmImpact='High')] + param( + [Parameter(Mandatory=$true)][String]$OrgName, + [Parameter(Mandatory=$true)][String]$SddcName, + [Parameter(Mandatory=$true)][Int]$HostCount, + [Parameter(Mandatory=$false)][ValidateSet("8","16","36","48")]$CPUCoreCount + ) + + if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } + + $orgId = Get-VMCOrg -Name $OrgName | Select-Object -ExpandProperty Id + $sddcId = Get-VMCSDDC -Name $SDDCName -Org $OrgName | Select-Object -ExpandProperty Id + + if(-not $orgId) { + Write-Host -ForegroundColor red "Unable to find Org $OrgName, please verify input" + break + } + if(-not $sddcId) { + Write-Host -ForegroundColor red "Unable to find SDDC $SDDCName, please verify input" + break + } + + $sddcClusterSvc = Get-VmcService -Name com.vmware.vmc.orgs.sddcs.clusters + + $sddcClusterCreateSpec = $sddcClusterSvc.Help.create.cluster_config.Create() + $sddcClusterCreateSpec.host_cpu_cores_count = $CPUCoreCount + $sddcClusterCreateSpec.num_hosts = $HostCount + + $sddcClusterTask = $sddcClusterSvc.Create($org.Id, $sddc.Id, $sddcClusterCreateSpec) + $sddcClusterTask | Select-Object Id,Task_Type,Status,Created | Format-Table +} +Function Remove-VMCSDDCCluster { + <# + .NOTES + =========================================================================== + Created by: Kyle Ruddy + Date: 03/16/2019 + Organization: VMware + Blog: https://www.kmruddy.com + Twitter: @kmruddy + =========================================================================== + + .SYNOPSIS + Removes a specified cluster from the designated SDDC + .DESCRIPTION + Deletes a cluster from an SDDC + .EXAMPLE + Remove-VMCSDDCCluster -OrgName -SDDCName -Cluster + #> + [cmdletbinding(SupportsShouldProcess = $true,ConfirmImpact='High')] + param( + [Parameter(Mandatory=$true)][String]$OrgName, + [Parameter(Mandatory=$true)][String]$SDDCName, + [Parameter(Mandatory=$true)][String]$ClusterName + ) + + if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } + + $orgId = Get-VMCOrg -Name $OrgName | Select-Object -ExpandProperty Id + $sddcId = Get-VMCSDDC -Name $SDDCName -Org $OrgName | Select-Object -ExpandProperty Id + $clusterId = Get-VMCSDDCCluster -SddcName $SDDCName -OrgName $OrgName | Where-Object {$_.Name -eq $ClusterName} | Select-Object -ExpandProperty Id + + if(-not $orgId) { + Write-Host -ForegroundColor red "Unable to find Org $OrgName, please verify input" + break + } + if(-not $sddcId) { + Write-Host -ForegroundColor red "Unable to find SDDC $SDDCName, please verify input" + break + } + if(-not $clusterId) { + Write-Host -ForegroundColor red "Unable to find cluster $ClusterName, please verify input" + break + } + + $sddcClusterTask = $sddcClusterSvc.Delete($orgId, $sddcId, $clusterId) + $sddcClusterTask | Select-Object Id,Task_Type,Status,Created | Format-Table +} Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', 'Get-VMCSDDCVersion', 'Get-VMCFirewallRule', 'Export-VMCFirewallRule', 'Import-VMCFirewallRule', 'Remove-VMCFirewallRule', 'Get-VMCLogicalNetwork', 'Remove-VMCLogicalNetwork', 'New-VMCLogicalNetwork', 'Get-VMCSDDCSummary', 'Get-VMCPublicIP', 'New-VMCPublicIP', 'Remove-VMCPublicIP', 'Set-VMCSDDC', - 'Get-VMCEdge', 'Get-VMCEdgeNic', 'Get-VMCEdgeStatus', 'Get-VMCEdgeNicStat', 'Get-VMCEdgeUplinkStat' - + 'Get-VMCEdge', 'Get-VMCEdgeNic', 'Get-VMCEdgeStatus', 'Get-VMCEdgeNicStat', 'Get-VMCEdgeUplinkStat', + 'Get-VMCSDDCCluster', 'New-VMCSDDCCluster', 'Remove-VMCSDDCCluster' \ No newline at end of file diff --git a/Scripts/Get-Migrations.ps1 b/Scripts/Get-Migrations.ps1 new file mode 100644 index 0000000..8336de7 --- /dev/null +++ b/Scripts/Get-Migrations.ps1 @@ -0,0 +1,12 @@ +<# +Script name: get-migrations.ps1 +Created on: 20/12/2018 +Author: Chris Bradshaw @aldershotchris +Description: The purpose of the script is to list the currently running + recently finished VM migrations. +Dependencies: None known +#> +Function Get-Migrations{ + Get-Task | + Where-Object{$_.Name -eq "RelocateVM_Task"} | + Select-Object @{Name="VM";Expression={Get-VM -Id $_.ObjectID}}, State, @{Name="% Complete";Expression={$_.PercentComplete}},StartTime +} diff --git a/Scripts/Move-DatastoreCluster.ps1 b/Scripts/Move-DatastoreCluster.ps1 new file mode 100644 index 0000000..a01d3bb --- /dev/null +++ b/Scripts/Move-DatastoreCluster.ps1 @@ -0,0 +1,34 @@ +function Move-DatastoreCluster { +<# +.SYNOPSIS + Moves a datastore cluster to a new location +.DESCRIPTION + Will move a datastore cluster to a new location +.NOTES + Author: Kyle Ruddy, @kmruddy +.PARAMETER DatastoreCluster + Specifies the datastore cluster you want to move. +.PARAMETER Destination + Specifies a destination where you want to place the datastore cluster +.EXAMPLE + Move-DatastoreCluster -DatastoreCluster $DSCluster -Destination $DSClusterFolder + Moves the $DSCluster datastore cluster to the specified $DSClusterFolder folder. +#> +[CmdletBinding(SupportsShouldProcess = $True)] + param( + [Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)] + [VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.DatastoreCluster]$DatastoreCluster, + [Parameter(Mandatory=$false,Position=1,ValueFromPipelineByPropertyName=$true)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.Folder]$Destination + ) + + if ($Global:DefaultVIServer.IsConnected -eq $false) { + Write-Warning -Message "No vCenter Server connection found." + break + } + + If ($Pscmdlet.ShouldProcess($DatastoreCluster,"Move Datastore Cluster")) { + $Destination.ExtensionData.MoveIntoFolder($DatastoreCluster.ExtensionData.MoRef) + } + +} \ No newline at end of file diff --git a/Scripts/Save-PowerCLI.ps1 b/Scripts/Save-PowerCLI.ps1 index e9127bc..495c153 100644 --- a/Scripts/Save-PowerCLI.ps1 +++ b/Scripts/Save-PowerCLI.ps1 @@ -1,147 +1,158 @@ -function Save-PowerCLI { - <# - .SYNOPSIS - Advanced function which can be used to easily download specific versions of PowerCLI from an online gallery - .DESCRIPTION - Downloads a specific version of PowerCLI and all the dependencies at the appropriate version - .NOTES - Author: 1.0 - Dimitar Milov - Author: 2.0 - Kyle Ruddy, @kmruddy - .PARAMETER RequiredVersion - Dynamic parameter used to specify the PowerCLI version - .PARAMETER Path - Directory path where the modules should be downloaded - .PARAMETER Repository - Repository to access the PowerCLI modules - .PARAMETER Simple - Switch used to specify the nested version folders should be removed (therefore adding PowerShell 3/4 compatibility) - .EXAMPLE - Save-PowerCLI -RequiredVersion '10.0.0.7895300' -Path .\Downloads\ - Downloads PowerCLI 10.0.0 to the Downloads folder - .EXAMPLE - Save-PowerCLI -RequiredVersion '6.5.2.6268016' -Path .\Downloads\ -Simple - Downloads PowerCLI 6.5.2 to the Downloads folder and removes the nested version folders - #> - [CmdletBinding(SupportsShouldProcess = $True)] - param( - [Parameter(Mandatory = $true, Position = 1)] - [ValidateScript( { Test-Path $_} )] - $Path, - [Parameter(Mandatory = $false, Position = 2)] - [string]$Repository = 'PSGallery', - [Parameter(Mandatory = $false, Position = 3)] - [Switch]$Simple - ) - DynamicParam - { - # Set the dynamic parameters name - $ParameterName = 'RequiredVersion' - - # Create the dictionary - $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary - - # Create the collection of attributes - $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] - - # Create and set the parameters' attributes - $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute - $ParameterAttribute.ValueFromPipeline = $true - $ParameterAttribute.ValueFromPipelineByPropertyName = $true - $ParameterAttribute.Mandatory = $true - $ParameterAttribute.Position = 0 - - # Add the attributes to the attributes collection - $AttributeCollection.Add($ParameterAttribute) - - # Generate and set the ValidateSet - $pcliVersions = Find-Module -Name 'VMware.PowerCLI' -AllVersions - $arrSet = $pcliVersions | select-Object -ExpandProperty Version - $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet) - - # Add the ValidateSet to the attributes collection - $AttributeCollection.Add($ValidateSetAttribute) - - # Create and return the dynamic parameter - $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection) - $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter) - return $RuntimeParameterDictionary +function Save-PowerCLI { +<# +.SYNOPSIS + Advanced function which can be used to easily download specific versions of PowerCLI from an online gallery +.DESCRIPTION + Downloads a specific version of PowerCLI and all the dependencies at the appropriate version +.NOTES + Author: 1.0 - Dimitar Milov + Author: 2.0 - Kyle Ruddy, @kmruddy + Author: 2.1 - Luc Dekens, @LucD22 + - fixed issue with downloading the correct versions + - added a working cleanup of unwanted versions +.PARAMETER RequiredVersion + Dynamic parameter used to specify the PowerCLI version +.PARAMETER Path + Directory path where the modules should be downloaded +.PARAMETER Repository + Repository to access the PowerCLI modules +.PARAMETER Simple + Switch used to specify the nested version folders should be removed (therefore adding PowerShell 3/4 compatibility) +.EXAMPLE + Save-PowerCLI -RequiredVersion '10.0.0.7895300' -Path .\Downloads\ + Downloads PowerCLI 10.0.0 to the Downloads folder +.EXAMPLE + Save-PowerCLI -RequiredVersion '6.5.2.6268016' -Path .\Downloads\ -Simple + Downloads PowerCLI 6.5.2 to the Downloads folder and removes the nested version folders +#> + [CmdletBinding(SupportsShouldProcess = $True)] + param( + [Parameter(Mandatory = $true, Position = 1)] + [ValidateScript( { Test-Path $_} )] + $Path, + [Parameter(Mandatory = $false, Position = 2)] + [string]$Repository = 'PSGallery', + [Parameter(Mandatory = $false, Position = 3)] + [Switch]$Simple + ) + DynamicParam + { + # Set the dynamic parameters name + $ParameterName = 'RequiredVersion' + + # Create the dictionary + $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary + + # Create the collection of attributes + $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] + + # Create and set the parameters' attributes + $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute + $ParameterAttribute.ValueFromPipeline = $true + $ParameterAttribute.ValueFromPipelineByPropertyName = $true + $ParameterAttribute.Mandatory = $true + $ParameterAttribute.Position = 0 + + # Add the attributes to the attributes collection + $AttributeCollection.Add($ParameterAttribute) + + # Generate and set the ValidateSet + $pcliVersions = Find-Module -Name 'VMware.PowerCLI' -AllVersions + $arrSet = $pcliVersions | select-Object -ExpandProperty Version + $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet) + + # Add the ValidateSet to the attributes collection + $AttributeCollection.Add($ValidateSetAttribute) + + # Create and return the dynamic parameter + $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [String], $AttributeCollection) + $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter) + return $RuntimeParameterDictionary + } + + begin { + $powercliModuleName = 'VMware.PowerCLI' + $desiredPowerCLIModule = Find-Module -Name $powercliModuleName -RequiredVersion $PSBoundParameters.RequiredVersion -Repository $Repository + + $depsOrder = 'VMware.VimAutomation.Sdk', 'VMware.VimAutomation.Common', 'VMware.Vim', 'VMware.VimAutomation.Cis.Core', 'VMware.VimAutomation.Core', 'VMware.VimAutomation.Nsxt', 'VMware.VimAutomation.Vmc', 'VMware.VimAutomation.Vds', 'VMware.VimAutomation.Srm', 'VMware.ImageBuilder', 'VMware.VimAutomation.Storage', 'VMware.VimAutomation.StorageUtility', 'VMware.VimAutomation.License', 'VMware.VumAutomation', 'VMware.VimAutomation.HorizonView', 'VMware.DeployAutomation', 'VMware.VimAutomation.vROps', 'VMware.VimAutomation.PCloud' + $orderedDependencies = @() + foreach ($depModuleName in $depsOrder) { + $orderedDependencies += $desiredPowerCLIModule.Dependencies | Where-Object {$_.Name -eq $depModuleName} } - - begin { - $powercliModuleName = 'VMware.PowerCLI' - $desiredPowerCLIModule = Find-Module -Name $powercliModuleName -RequiredVersion $RequiredVersion -Repository $Repository - - $depsOrder = 'VMware.VimAutomation.Sdk', 'VMware.VimAutomation.Common', 'VMware.Vim', 'VMware.VimAutomation.Cis.Core', 'VMware.VimAutomation.Core', 'VMware.VimAutomation.Nsxt', 'VMware.VimAutomation.Vmc', 'VMware.VimAutomation.Vds', 'VMware.VimAutomation.Srm', 'VMware.ImageBuilder', 'VMware.VimAutomation.Storage', 'VMware.VimAutomation.StorageUtility', 'VMware.VimAutomation.License', 'VMware.VumAutomation', 'VMware.VimAutomation.HorizonView', 'VMware.DeployAutomation', 'VMware.VimAutomation.vROps', 'VMware.VimAutomation.PCloud' - $orderedDependencies = @() - foreach ($depModuleName in $depsOrder) { - $orderedDependencies += $desiredPowerCLIModule.Dependencies | Where-Object {$_.Name -eq $depModuleName} + + foreach ($remainingDep in $desiredPowerCLIModule.Dependencies) { + if ($orderedDependencies.Name -notcontains $remainingDep.Name) { + $orderedDependencies += $remainingDep } - foreach ($remainingDep in $desiredPowerCLIModule.Dependencies) { - if ($orderedDependencies.Name -notcontains $remainingDep.Name) { - $orderedDependencies += $remainingDep - } - + } + } + + process { + # Save PowerCLI Module Version + $desiredPowerCLIModule | Save-Module -Path $Path + + # Working with the depenent modules + foreach ($dependency in $orderedDependencies) { + if (Get-ChildItem -Path (Join-Path $path $dependency.Name) | Where-Object {$_.Name -ne $dependency.MinimumVersion}) { + # Save dependencies with minimum version + Find-Module $dependency.Name -RequiredVersion $dependency.MinimumVersion | Save-Module -Path $Path } } - - process { - # Save PowerCLI Module Version - $desiredPowerCLIModule | Save-Module -Path $Path - - # Working with the depenent modules - foreach ($dependency in $orderedDependencies) { - if (Get-ChildItem -Path (Join-Path $path $dependency.Name) | Where-Object {$_.Name -ne $dependency.MinimumVersion}) { - # Save dependencies with minimum version - Find-Module $dependency.Name -RequiredVersion $dependency.MinimumVersion | Save-Module -Path $Path - - # Remove newer dependencies version - Get-ChildItem -Path (Join-Path $path $dependency.Name) | Where-Object {$_.Name -ne $dependency.MinimumVersion} | Remove-Item -Confirm:$false -Force -Recurse + } + + end { + Get-Item -Path "$($Path)\*" -PipelineVariable dir | + ForEach-Object -Process { + $children = Get-ChildItem -Path $dir.FullName -Directory + if($children.Count -gt 1){ + $tgtVersion = $orderedDependencies.GetEnumerator() | where {$_.Name -eq $dir.Name} + $children | where{$_.Name -ne $tgtVersion.MinimumVersion} | + ForEach-Object -Process { + Remove-Item -Path $_.FullName -Recurse -Force -Confirm:$false } } } - - end { - if ($Simple) { - - function FolderCleanup { - param( - [Parameter(Mandatory = $true, Position = 0)] - [ValidateScript( { Test-Path $_} )] - $ParentFolder, - [Parameter(Mandatory = $true, Position = 1)] - [String]$ModuleName, - [Parameter(Mandatory = $true, Position = 2)] - $Version - ) - - - $topFolder = Get-Item -Path (Join-Path $ParentFolder $ModuleName) - $versionFolder = $topFolder | Get-ChildItem -Directory | Where-Object {$_.Name -eq $Version} - $versionFolder | Get-ChildItem | Copy-Item -Destination $topFolder - - # Checking for any nested folders within the PowerCLI module version folder - if ($versionFolder| Get-ChildItem -Directory) { - - # Obtaining and storing the child items to a variable, then copying the items to the parent folder's nested folder - $nestFolder = $versionFolder| Get-ChildItem -Directory - foreach ($nestDir in $nestFolder) { - $nestDir | Get-ChildItem | Copy-Item -Destination (Join-Path $topFolder $nestDir.Name) - } - + + if ($Simple) { + + function FolderCleanup { + param( + [Parameter(Mandatory = $true, Position = 0)] + [ValidateScript( { Test-Path $_} )] + $ParentFolder, + [Parameter(Mandatory = $true, Position = 1)] + [String]$ModuleName, + [Parameter(Mandatory = $true, Position = 2)] + $Version + ) + + + $topFolder = Get-Item -Path (Join-Path $ParentFolder $ModuleName) + $versionFolder = $topFolder | Get-ChildItem -Directory | Where-Object {$_.Name -eq $Version} + $versionFolder | Get-ChildItem | Copy-Item -Destination $topFolder + + # Checking for any nested folders within the PowerCLI module version folder + if ($versionFolder| Get-ChildItem -Directory) { + + # Obtaining and storing the child items to a variable, then copying the items to the parent folder's nested folder + $nestFolder = $versionFolder| Get-ChildItem -Directory + foreach ($nestDir in $nestFolder) { + $nestDir | Get-ChildItem | Copy-Item -Destination (Join-Path $topFolder $nestDir.Name) } - - # Removing any of the former, no longer needed, directory structure - $versionFolder| Remove-Item -Recurse -Force + } - - FolderCleanup -ParentFolder $Path -ModuleName $desiredPowerCLIModule.Name -Version $desiredPowerCLIModule.Version - foreach ($cleanUp in $orderedDependencies) { - - FolderCleanup -ParentFolder $Path -ModuleName $cleanUp.Name -Version $cleanUp.MinimumVersion - } - + + # Removing any of the former, no longer needed, directory structure + $versionFolder| Remove-Item -Recurse -Force } - + + FolderCleanup -ParentFolder $Path -ModuleName $desiredPowerCLIModule.Name -Version $desiredPowerCLIModule.Version + foreach ($cleanUp in $orderedDependencies) { + + FolderCleanup -ParentFolder $Path -ModuleName $cleanUp.Name -Version $cleanUp.MinimumVersion + } + } - } \ No newline at end of file + } +} diff --git a/Scripts/Set-NetworkAdapterOpaqueNetwork.ps1 b/Scripts/Set-NetworkAdapterOpaqueNetwork.ps1 new file mode 100644 index 0000000..1310734 --- /dev/null +++ b/Scripts/Set-NetworkAdapterOpaqueNetwork.ps1 @@ -0,0 +1,50 @@ +function Set-NetworkAdapterOpaqueNetwork { +param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 1)] + [VMware.VimAutomation.Types.NetworkAdapter] + $NetworkAdapter, + + [Parameter(Mandatory = $true, Position = 2)] + [string] + $OpaqueNetworkName, + + [Parameter()] + [switch] + $Connected, + + [Parameter()] + [switch] + $StartConnected +) +process { + $opaqueNetwork = Get-View -ViewType OpaqueNetwork | ? {$_.Name -eq $OpaqueNetworkName} + if (-not $opaqueNetwork) { + throw "'$OpaqueNetworkName' network not found." + } + + $opaqueNetworkBacking = New-Object VMware.Vim.VirtualEthernetCardOpaqueNetworkBackingInfo + $opaqueNetworkBacking.OpaqueNetworkId = $opaqueNetwork.Summary.OpaqueNetworkId + $opaqueNetworkBacking.OpaqueNetworkType = $opaqueNetwork.Summary.OpaqueNetworkType + + $device = $NetworkAdapter.ExtensionData + $device.Backing = $opaqueNetworkBacking + + if ($StartConnected) { + $device.Connectable.StartConnected = $true + } + + if ($Connected) { + $device.Connectable.Connected = $true + } + + $spec = New-Object VMware.Vim.VirtualDeviceConfigSpec + $spec.Operation = [VMware.Vim.VirtualDeviceConfigSpecOperation]::edit + $spec.Device = $device + $configSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $configSpec.DeviceChange = @($spec) + $NetworkAdapter.Parent.ExtensionData.ReconfigVM($configSpec) + + # Output + Get-NetworkAdapter -Id $NetworkAdapter.Id + } +}