vSphereDSCHelper.ps1
enum VmwFolderType { Yellow Blue } function Enable-PowerCLI { <# .SYNOPSIS Load PowerCLI modules and PSSnapins .DESCRIPTION This function will load all requested PowerCLI modules and PSSnapins. The function will, depending on the installed PowerCLI version, determine what needs to be loaded. .NOTES Author: Luc Dekens .PARAMETER Cloud Switch to indicate if the Cloud related cmdlets shall be loaded .PARAMETER InitScript The PowerCLI PSSnapin have associated initialisation scripts. This switch will indicate if that script needs to be executed or not. .EXAMPLE PS> Enable-PowerCLI .EXAMPLE PS> Enable-PowerCLI -Cloud #> [CmdletBinding()] param( [switch]$Cloud=$false, [switch]$InitScript=$true ) Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Entering {0}" -f $s[0].FunctionName)" $Global:PSDefaultParameterValues = @{ "Get-View:Verbose"=$false "Add-PSSnapin:Verbose"=$false "Import-Module:Verbose"=$false } $PcliPssnapin = @{ 'VMware.VimAutomation.License' = @(2548067) 'VMware.DeployAutomation' =@(2548067,3056836,3205540,3737840) 'VMware.ImageBuilder' = @(2548067,3056836,3205540,3737840) } $PcliModule = @{ 'VMware.VimAutomation.Core' = @(2548067,3056836,3205540,3737840) 'VMware.VimAutomation.Vds' = @(2548067,3056836,3205540,3737840) 'VMware.VimAutomation.Cloud' = @(2548067,3056836,3205540,3737840) 'VMware.VimAutomation.PCloud' = @(2548067,3056836,3205540,3737840) 'VMware.VimAutomation.Cis.Core' = @(2548067,3056836,3205540,3737840) 'VMware.VimAutomation.Storage' = @(2548067,3056836,3205540,3737840) 'VMware.VimAutomation.HA' = @(2548067,3056836,3205540,3737840) 'VMware.VimAutomation.vROps' = @(3056836,3205540,3737840) 'VMware.VumAutomation' = @(3056836,3205540,3737840) 'VMware.VimAutomation.License' = @(3056836,3205540,3737840) } # 32- or 64-bit process $procArch = (Get-Process -Id $Global:pid).StartInfo.EnvironmentVariables["PROCESSOR_ARCHITECTURE"] if($procArch -eq 'x86'){ $regPath = 'HKLM:\Software\VMware, Inc.\VMware vSphere PowerCLI' } else{ $regPath = 'HKLM:\Software\WOW6432Node\VMware, Inc.\VMware vSphere PowerCLI' } # Check if PowerCLI (regular or Tenant) is installed if(!(Test-Path -Path $regPath)) { $regPath = $regPath.Replace('VMware vSphere PowerCLI','VMware vSphere PowerCLI for Tenants') if(!(Test-Path -Path $regPath)) { Throw 'Can not find a PowerCLI installation!' } } # Get build $buildKey = 'InstalledBuild' Try{ $pcliBuild = Get-ItemProperty -Path $regPath -Name $buildKey | Select -ExpandProperty $buildKey -ErrorAction Stop } Catch{ Throw "PowerCLI doesn't seem to be installed on this system!" } # Get installation path $installPathKey = 'InstallPath' Try{ $pcliInstallPath = Get-ItemProperty -Path $regPath -Name $installPathKey | Select -ExpandProperty $installPathKey -ErrorAction Stop } Catch{ Throw "PowerCLI doesn't seem to be installed on this system!" } # Load modules if($pcliBuild -ge 2548067) { $loadedModule = Get-Module -Name VMware* -ErrorAction SilentlyContinue | %{$_.Name} if($loadedModule -and $pcliBuild -ge 3737840) { $loadedModule = $loadedModule | where{$_ -notmatch 'Common$|SDK$'} } $targetModule = $PcliModule.GetEnumerator() | where{$_.Value -contains $pcliBuild} | %{$_.Key} $targetModule = $targetModule | where{$loadedModule -notcontains $_} if(!$Cloud) { $targetModule = $targetModule | where{$_ -notmatch 'Cloud'} } if($targetModule) { $targetModule | where{$loadedModule -notcontains $_.Name} | %{ Import-Module -Name $_ } } } # Load PSSnapin $loadedSnap = Get-PSSnapin -Name VMware* -ErrorAction SilentlyContinue -Verbose:$false | %{$_.Name} if($pcliBuild -ge 3737840) { $loadedSnap = $loadedSnap | where{$_ -notmatch 'Core$'} } $targetSnap = $PcliPssnapin.GetEnumerator() | where{$_.Value -contains $pcliBuild} | %{$_.Key} $targetSnap = $targetSnap | where{$loadedSnap -notcontains $_} if(!$Cloud) { $targetSnap = $targetSnap | where{$_ -notmatch 'Cloud'} } if($targetSnap) { $targetSnap | where{$loadedSnap -notcontains $_} | %{ Add-PSSnapin -Name $_ # Run initialisation script if($InitScript) { $filePath = "{0}Scripts\Initialize-{1}.ps1" -f $pcliInstallPath,$_.ToString().Replace(".", "_") if (Test-Path $filePath) { & $filePath } } } } # $global:VerbosePreference = $SaveVerbosePreference Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Leaving {0}" -f $s[0].FunctionName)" } function Connect-VmwVIServer { [CmdletBinding()] [OutputType([System.String])] param( [string]$Server, [PSCredential]$Credential, [string]$Id ) Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Entering {0}" -f $s[0].FunctionName)" Write-Verbose -Message "$(Get-Date) Connect with credential $($Credential.UserName)" Write-Verbose -Message "$(Get-Date) SessionId $($Id)" Enable-PowerCLI Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -DisplayDeprecationWarnings $false -Confirm:$false | Out-Null $srv = Connect-VIServer -Server $Server -Credential $Credential Write-Verbose -Message "$(Get-Date) Connected with credential $($Credential.UserName)" Write-Verbose -Message "$(Get-Date) $('Got session ID {0}' -f $srv.SessionId)" return $srv.SessionId Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Leaving {0}" -f $s[0].FunctionName)" } function Get-VmwNodeFromPath { [CmdletBinding()] [OutputType([System.Management.Automation.PSCustomObject])] param( [PSObject]$StartNode = (Get-View -Id (Get-View -Id ServiceInstance).Content.RootFolder), [String]$Path ) function Get-NodeChild{ param( [VMware.Vim.ManagedEntity]$Node ) $hidden = 'vm','host','network','datastore','Resources' switch($Node){ {$_ -is [VMware.Vim.Folder]}{ if($Node.ChildEntity){ Get-View -Id $Node.ChildEntity } } {$_ -is [VMware.Vim.Datacenter]}{ $all = @() $all += Get-View -Id $Node.VmFolder $all += Get-View -Id $Node.HostFolder $all += Get-View -Id $Node.DatastoreFolder $all += Get-View -Id $Node.NetworkFolder $all | %{ if($hidden -contains $_.Name){ Get-NodeChild -Node $_ } else{ $_ } } } {$_ -is [VMware.Vim.ClusterComputeResource]}{ $all = @() $all += Get-View -Id $Node.Host $all += Get-View -Id $Node.ResourcePool $all = $all | %{ if($hidden -contains $_.Name){ Get-NodeChild -Node $_ } else{ $_ } } $all } {$_ -is [VMware.Vim.ResourcePool]}{ $all = @() if($Node.ResourcePool){ $all += Get-View -Id $Node.ResourcePool } if($Node.vm){ $all += Get-View -Id $Node.vm } $all } {$_ -is [VMware.Vim.DistributedVirtualSwitch]}{ Get-View -Id $Node.Portgroup } } } Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Entering {0}" -f $s[0].FunctionName)" Write-Verbose -Message "$(Get-Date) Start: $($StartNode.Name)" Write-Verbose -Message "$(Get-Date) Path: $($Path)" $found = $true # Loop through Path $node = @($StartNode) foreach($qualifier in $Path.TrimStart('/').Split('/',[StringSplitOptions]::RemoveEmptyEntries)){ $nodeMatch = @($node) | %{ Get-NodeChild -Node $_ | where{$_.Name -eq $qualifier} } if(!$nodeMatch){ $found = $false $node = $null break } $node = $nodeMatch } Write-Verbose -Message "$(Get-Date) Nodes found $($node.Count)" Write-Verbose -Message "$(Get-Date) Nodes: $(($node | %{$_.Name}) -join '|')" if($node -eq $null){ return New-Object PSObject -Property @{ Path = $Path Found = $false Node = $null } } else{ @($node) | %{ return New-Object PSObject -Property @{ Path = $Path Found = $true Node = $_ } } } Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Leaving {0}" -f $s[0].FunctionName)" } function Test-VmwNodePath { [CmdletBinding()] [OutputType([System.Boolean])] param( [PSObject]$StartNode = (Get-View -Id (Get-View -Id ServiceInstance).Content.RootFolder), [String]$Path ) Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Entering {0}" -f $s[0].FunctionName)" Write-Verbose -Message "$(Get-Date) Start: $($StartNode.Name)" Write-Verbose -Message "$(Get-Date) Path: $($Path)" $nodeObj = Get-VmwNodeFromPath -StartNode $StartNode -Path $Path return $nodeObj.Found Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Leaving {0}" -f $s[0].FunctionName)" } function New-VmwFolder { [CmdletBinding()] param( [VMware.Vim.ManagedEntity]$Parent, [String]$FolderName, [VmwFolderType]$FolderType ) Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Entering {0}" -f $s[0].FunctionName)" Write-Verbose -Message "$(Get-Date) Create a $($FolderType) folder, named $($FolderName), in $($Parent.Name) " if($parent -is [VMware.Vim.Datacenter]){ if($FolderType -eq [VmwFolderType]::Blue){ $Parent.UpdateViewData('VmFolder') $leaf = Get-view -Id $parent.VmFolder -Property Name } else{ $Parent.UpdateViewData('HostFolder') $leaf = Get-view -Id $parent.HostFolder -Property Name } } else{ $leaf = $Parent } Write-Verbose -Message "$(Get-Date) Creating folder $($FolderName) at $($leaf.Name)" $leaf.CreateFolder($FolderName) | Out-Null Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Leaving {0}" -f $s[0].FunctionName)" } function Test-VmwFolderType { [CmdletBinding()] [OutputType([System.Boolean])] param( [VMware.Vim.ManagedEntity]$Node, [VmwFolderType]$FolderType ) Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Entering {0}" -f $s[0].FunctionName)" Write-Verbose -Message "$(Get-Date) Testing if folder $($Node.Name) is $($FolderType)" if($FolderType -eq [VmwFolderType]::Yellow) { $targetParent = 'host' } else { $targetParent = 'vm' } $si = Get-View -Id ServiceInstance $rootFolder = Get-View -Id $si.Content.RootFolder $foundType = $false if($Node.Parent -eq $rootFolder.MoRef -and $FolderType -eq [VmwFolderType]::Yellow){ $foundType = $true } else{ while($Node.Parent -ne $null){ $Node = Get-View -Id $Node.Parent if($Node -is [VMware.Vim.Folder] -and $Node.Name -eq $targetParent){ $foundType = $true break } } } Write-Verbose -Message "$(Get-Date) FoundType: $($foundType)" Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Leaving {0}" -f $s[0].FunctionName)" return $foundType } function Test-VmwDatacenterIsNested { [CmdletBinding()] param( [VMware.Vim.ManagedEntity]$Node ) $isNested = $false $parent = $Node.Parent while($parent){ $parentObj = Get-View -Id $parent -Property Name,Parent if($parentObj -is [VMware.Vim.Datacenter]){ $isNedsted = $true } $parent = $parentObj.Parent } } function New-VmwDatacenter { [CmdletBinding()] param( [VMware.Vim.ManagedEntity]$Parent, [String]$DatacenterName ) Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Entering {0}" -f $s[0].FunctionName)" Write-Verbose -Message "$(Get-Date) Create a datacenter, named $($DatacenterName), in $($Parent.Name) " $si = Get-View -Id ServiceInstance $rootFolder = Get-View -Id $si.Content.RootFolder if($parent -is [VMware.Vim.Folder] -and (($parent.MoRef -eq $si.Content.RootFolder) -or (Test-VmwFolderType -Node $Parent -FolderType ([VmwFolderType]::Yellow))) -and !(Test-VmwDatacenterIsNested -Node $Parent)){ Write-Verbose -Message "$(Get-Date) Creating datacenter $($DatacenterName) at $($Parent.Name)" $Parent.CreateDatacenter($DatacenterName) | Out-Null } Write-Verbose -Message "$(Get-Date) $($s = Get-PSCallStack;"Leaving {0}" -f $s[0].FunctionName)" } |