好贷网好贷款

自動擴展VDI虛擬桌面集區,並自動指派

发布时间:2016-12-4 5:54:29 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"自動擴展VDI虛擬桌面集區,並自動指派",主要涉及到自動擴展VDI虛擬桌面集區,並自動指派方面的内容,对于自動擴展VDI虛擬桌面集區,並自動指派感兴趣的同学可以参考一下。

這篇是個概念性的文章 要用在Production Server上請三思而後行 基本上,Microsoft的VDI是透過MSDTC來Remote Desktop到Hyper-V上的Virtual Machine 而Microsoft的VDI有分為Virtual Desktop Pool跟One by One Virtaul Desktop 在做Virtual Desktop Pool時會有一個考量點,就是VM的數量會比實際上使用者來的少 如果建的比實際上使用的使用者來的多,就失去了Virtual Desktop Pool的意義 (當然還有節省One by One Virtaul Desktop管理VM的麻煩) 下圖是一張VDI的簡單概念圖,SCVMM並不是必要的,會畫上去是因為這篇會用到 原則上一台Windows 7的Virtual Machine一次只能允許一個RDP Session 如果是One By One的Virtual Desktop,以兩百個使用者為例,就需要建立兩百個Win7的VM 但是如果不會同時達到200人同時使用,其實就可以考慮用Pool的形式 像是一開始只建立50台VM,但一樣實際使用者有200個,這情況下,在第51個使用者使用時,會出現VM不足的問題 如果以手動的方式,我們需要建立一台VM,然後設定VDI相關設定再Win7 VM上,再指派給RDCB的Virtual Pool 這樣子,這台VM才能被使用為VDI的一部VM 這篇主要就是要解決這個問題,但是只是概念,如一開始所說,要用請三思:P OK,既然已經知道,RDCB是以Machine的RDP Session來記錄是否有使用 那麼我們要如何得知這台Machine是否有Online的RDP Session呢? 我們可以透過這個PowerShell Module來取得Online Session 語法是Get-TSSession -ComputerName $ComsputeName.Computername -State Active 我這裡提供一份自動AssinVMPool的Powershell,寫得不是很好,算是個半成品,有興趣的人可以自己改,算是個概念性提供 這裡面會牽涉到VMM的Template的建立、RDCB的Pool Assin、RDP Session的Monitor、也用到了一些Remote Manager的指令 這個指令需要放在VMM Server上,並且VMM需要安裝 VMM Server對RDCB需要啟用WinRM,這牽涉到送指令給RDCB做AssinVMPool,並且SMB要通,權限要夠 裡面當中,唯一會需要修改的大概只有下面這個PowerShell Script 第五行是取得SCVMM的Server內容,SCVMM是我的Hostname,請自行修改(只要是SCVMM都是) 第九行跟第十行以及第十四行是我針對Win7 VM的Hostname前置名稱,請依個人需求修改 第十五行是網域尾碼,請依自行環境修改 第27行的Win7SP1_Pro_zh-tw_Template是我的Template Name,這需要先在VMM中先建立好 第28行則是我的Hyper-V Host Name 第35行跟第52行則是有vSwitch的名稱,請依個人環境設定 第8行跟第58行及第60行有RDCB的HostName,請自行修改,另外第60行會有Administrator的Password 第7行則是當VM的Online Session比例達到70%(0.7)時,就會建立VM 第29行則是一次要建立幾個VM(範例是指定2個) 第40行則需要修改VM Pools的名稱,我的Pool Nam是POOL VMPOOL 如果要快速建立,可以使用差異磁碟去建立,數分鐘就可以完成幾十個 至於VMM裡的Template需要建立到甚麼樣的程度? 其實只要讓它建立完VM,會自動加入網域就可以了(所以會需要DHCP Server) 01Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager 03Import-Module PSTerminalServices 05Get-VMMServer -ComputerName SCVMM 07Clear-Content C:\1.csv 08Clear-Content \\RDCB\C$\Assin.txt 09$a=get-vm | where { $_.Computername -Like "*vdiclient*"} |ft|Measure-Object -line 10$w=get-vm | where { $_.Computername -Like "*vdiclient*"}  11$b = $a.Lines -4 14$computername="vdiclient" 16$w | foreach{ 18{Get-TSSession -ComputerName $_.Computername -State Active}catch{add-content -value "$_.Computername+' Connection Error'" -Path C:\Error.log}}|select Computername|add-content C:\1.csv 19$x =Get-Content C:\1.csv|Measure-Object -line 20$d=$x.Lines 21if($d -gt 0) 23if($b/$d -gt 0.7 ) 25 27$Template = Get-Template -VMMServer "SCVMM" | where {$_.Name -eq "Win7SP1_Pro_zh-tw_Template"} 29while($s -le 2) 31$jobgroup1="02ff3a4c-f3a0-43bf-9acc-" 32$jobgroup2=100 33$jobgroup3=get-random -minimum 100000000 -maximum 999999999 34$jobgroup=$jobgroup1+$jobgroup2+$jobgroup3 35New-VirtualNetworkAdapter -VMMServer "SCVMM" -JobGroup $jobgroup -PhysicalAddressType Dynamic -VirtualNetwork "VM-Public-10.1.1.0-24" -VLanEnabled $false -Synthetic -VMNetworkOptimizationEnabled $false -MACAddressesSpoofingEnabled $false 37$tempname=$computername+$b+$fqdn 38$tempcomputername=$computername+$b 40New-VM -Template $Template -Name $tempname -JobGroup $jobgroup -VMHost $VMHost -Path "C:\ClusterStorage\Volume1\" -RunAsynchronously -ComputerName $tempcomputername -DelayStart 0 -StopAction SaveVM -StartVM  41$TempAssignment=$tempname+" POOL VMPOOL" 42$TempAssignment|add-content \\RDCB\C$\Assin.txt 44 45 46Start-Sleep -Seconds 5 48$jobgroup1="02ff3a4c-f3a0-43bf-9acc-" 49$jobgroup2=100 50$jobgroup3=get-random -minimum 100000000 -maximum 999999999 51$jobgroup=$jobgroup1+$jobgroup2+$jobgroup3 52New-VirtualNetworkAdapter -VMMServer "SCVMM" -JobGroup $jobgroup -PhysicalAddressType Dynamic -VirtualNetwork "VM-Public-10.1.1.0-24" -VLanEnabled $false -Synthetic -VMNetworkOptimizationEnabled $false -MACAddressesSpoofingEnabled $false 53$tempname=$computername+$b+$fqdn 54$tempcomputername=$computername+$b 56New-VM -Template $Template -Name $tempname -JobGroup $jobgroup -VMHost $VMHost -Path "C:\ClusterStorage\Volume1\" -ComputerName $tempcomputername -DelayStart 0 -StopAction SaveVM -StartVM 57$TempAssignment=$tempname+" POOL VMPOOL" 58$TempAssignment|add-content \\RDCB\C$\Assin.txt 因為要透過RDCB執行Assin VM的指令,會需要將Set-VMAssignment.ps1放到RDCB的C:上 Set-VMAssignment.ps1內容如下: 001<#   002.Synopsis   003Assigns virtual machines to users or pools. The script, optionally also adds RD Virtualization Host servers to the RD Connection Broker server.  005.Description   006Assigns virtual machines to users or pools. The script, optionally also adds RD Virtualization Host servers to the RD Connection Broker server. While assigning personal virtual desktops, the script prompts for confirmation to continue overriding the current assignment (if any) for the virtual machines.  007NOTE: This script should be run on the RD Connection Broker server.  009.Parameter AssignmentFileName  010Text file containing assignment information in the format '<VMName> [POOL|USER] <User Name/Pool Name>'. User Name should be in 'domain\user' format.  012.Parameter HostFileName  013Text file containing list of RD Virtualization Host servers that need to be added to the connection broker. Each new line seperated entry in the file is treated as a single RD Virtual Host server's name.  015.Parameter PoolFileName  016Text file containing list of pools that need to be created. Each new line seperated entry in the file is treated as the name of a pool.  018.Parameter Credential  019Credentials that have write acces on the Active Directory for Personal Virtual Desktop assignment.  021.Parameter Force  022Switch: The script seeks confirmation from the user in case it is reassigning a virtual machine to another user unless this switch is used. Providing this switch would force continue the reassignment.  024.Example   025PS C:\> Set-VMAssignment.ps1 -AssignmentFileName "C:\Users\Administrator\Desktop\assninfo.txt"  027The above example performs virtual machine assignment as mentioned in 'assninfo.txt'.  029.Example   030PS C:\> Set-VMAssignment.ps1 -AssignmentFileName "C:\Users\Administrator\Desktop\assninfo.txt" -PoolFileName "C:\Users\Administrator\Desktop\pools.txt"  032The above example creates virtual machine pools with names mentioned in 'pools.txt' and performs virtual machine assignment as mentioned in 'assninfo.txt'.  034.Example   035PS C:\> Set-VMAssignment.ps1 -AssignmentFileName "C:\Users\Administrator\Desktop\assninfo.txt" -PoolFileName "C:\Users\Administrator\Desktop\pools.txt" -HostFileName "C:\Users\Administrator\Desktop\hosts.txt"  037The above example adds entries mentioned in 'hosts.txt' as RD Virtualization Host servers to the RD Connection Borker server on which the script is being executed, creates virtual machine pools with names mentioned in 'pools.txt' and performs virtual machine assignment as mentioned in 'assninfo.txt'.  039.Notes   040Name     : Set-VMAssignment.ps1  042#>  043param (  044[Parameter(Mandatory=$TRUE, HelpMessage="Text file containing lines in the format '<VM Name> [POOL/USER] <Pool Name/User Name>'.")]  045[string]$AssignmentFileName,  047[Parameter(Mandatory=$FALSE, HelpMessage="Text file containing servers which should be added to the RD Connection Broker server as RD Virtualization Host servers.")]  048[string]$HostFileName,  050[Parameter(Mandatory=$FALSE, HelpMessage="Text file containing the names of pools that need to be created on the RD Connection Broker server.")]  051[string]$PoolFileName,  053[Parameter(Mandatory=$FALSE, HelpMessage="Credentials that have write acces on the Active Directory for Personal Virtual Desktop assignment.")]  054[System.Management.Automation.PSCredential]$Credential,  056[Parameter(Mandatory=$FALSE, HelpMessage="The script seeks confirmation from the user in case it is reassigning a virtual machine to another user unless this switch is used. Providing this switch would force continue the reassignment.")]  057[Switch]$Force  060function Print-Error([System.String]$Msg)  062Write-Host $Msg  063Exit(1)  066function Ask-Confirmation()  068Write-Warning "The script will not check for current user assignment of Virtual Machines. A virtual machine already assigned to a user might be reassigned to a new user depending on the entries in the 'AssignmentFile'."  069Write-Host  "Do you want to continue? : [Y]Yes, [N]No"  070while($TRUE)  072return  076#Check if there are proper privileges to run the script  077$LoggedInUser = New-Object -TypeName System.Security.Principal.WindowsPrincipal -ArgumentList ([System.Security.Principal.WindowsIdentity]::GetCurrent())  078if(!($LoggedInUser.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)))  080Print-Error "Please execute the script with administrative privileges! Exiting..."  083Import-Module ServerManager  084$RoleInstalled = (Get-WindowsFeature RDS-Connection-Broker).Installed  085Remove-Module ServerManager  087if(!$RoleInstalled)  089Print-Error "This script should be run on the RD Connection Broker server! Exiting..."  093$LineFormat="<VM Name> [POOL/USER] <Pool Name/User Name>"  095# File Format  096# <VMName> [POOL/USER] <farm name/user name>  098#Add RD Virtualization Host servers if needed  099function Add-VirtualizationHostServer([string]$FileName)  101$servers=(Get-Content -Path $FileName)  102foreach($server in $servers)  104New-Item -Path "RDS:\ConnectionBroker\VirtualDesktops\RDVHostServers" -Name $server  107Start-Sleep -seconds 5  110#Create Farms  111function Add-VmFarm([string]$FileName)  113$farms=(Get-Content -Path $FileName)  114foreach($farm in $farms)  116New-Item -Path RDS:\ConnectionBroker\VirtualDesktops\Pools -Name $farm -DisplayName $farm  120#Assign function  121function Assign-VirtualMachines([string]$FileName)  123if(!$Force.IsPresent)  125Ask-Confirmation  128 129foreach($Line in (Get-Content -Path $FileName))  131$tokens = $Line.Trim().Split()  132if(($tokens) -and ($tokens.Length -eq 3))  134if($tokens[1] -eq "POOL")  136New-Item -Path "RDS:\ConnectionBroker\VirtualDesktops\Pools\$($tokens[2])\VirtualMachines" -Name $tokens[0]  137if(!$?)  139Write-Error "ERROR in Line '$i': Could not create a pool with name $($tokens[0])"  142 144if($tokens[1] -eq "USER")  146if($Credential)  148Set-PersonalVirtualDesktop -User $tokens[2] -VirtualDesktop $tokens[0] -Credential $Credential  150 152Set-PersonalVirtualDesktop -User $tokens[2] -VirtualDesktop $tokens[0]  155 157$VMObject = Get-VirtualDesktop -User $tokens[2]  158Write-Host "Virtual machine: '$($VMObject.Name)' assigned to: '$($tokens[2])'"  160 162Write-Error "ERROR in Line '$i': Could not assign virtual machine: '$($tokens[0])' to '$($tokens[2])'"  163Write-Error "You may want to use the script, Verify-VMConfiguration.ps1, to verify the configuration of virtual machine so that it can be used as a virtual desktop in RemoteApp and Desktop Connection." 168Write-Error "Error in Line $i: Line in unexpected format. Expected Format: $LineFormat" 174if(($tokens) -and ($tokens.Length -gt 0))  176Write-Error "Error in Line $i: Line in unexpected format. Expected Format: $LineFormat" 179 183Import-Module RemoteDesktopServices  185#Add Virtualization Host Servers  186if($HostFileName)  188Add-VirtualizationHostServer($HostFileName)  191if($PoolFileName)  193Add-VmFarm($PoolFileName)  196if($AssignmentFileName)  198Assign-VirtualMachines($AssignmentFileName)  然後在透過SCVMM對Win7做Sysprep前先將這個Configure-VirtualMachine PowerShell執行一遍,這樣可以加快設定 如果可以,請將他放入GPO中套用到VDI的VM OU中,並在GPO中預先啟用遠端桌面並指派VDI使用者可登入 001param (  002[ValidatePattern("(.+)\\(.+)")]  003[Parameter(Mandatory=$TRUE, Position=0, HelpMessage="RD Virtualization Host server")]  004[string[]]  005$RDVHost,  007[ValidatePattern("(.+)\\(.+)")]  008[Parameter(Mandatory=$FALSE, Position=1, HelpMessage="Remote Desktop Users")]  009[string[]]  010$RDUsers,  012[Parameter(Mandatory=$FALSE, Position=2, HelpMessage="File to which events are to be logged")]  013[string]  014$LogFile = ".\Configure-VirtualMachine.log",  016[Parameter(Mandatory=$FALSE, HelpMessage="Option not to restart the Remote Desktop Services service")]  017[switch]  018$DoNotRestartService,  020[Parameter(Mandatory=$FALSE, HelpMessage="Option to ignore verification of object when credentials are not valid")]  021[switch]  022 025function Write-Log ([string]$Message = "", [string]$Type = "verbose")  027switch ($Type)  029"error"       {Write-Error $Message}  030"warning"     {Write-Warning $Message}  031"verbose"     {Write-Verbose $Message}  032"host"        {Write-Host $Message}  033"initialize"  { "" > $LogFile; return }  036$Message >> $LogFile  039#   Check if the script is running with administrator/elevated privileges  040function Check-Credentials  042$principal = New-Object Security.Principal.WindowsPrincipal ([Security.Principal.WindowsIdentity]::GetCurrent())  043$elevated = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)    045if (-not $elevated)  047Write-Error "Please run this script in an elevated shell!" 048 052function Grant-RDPPermissions([String]$RDVHost, [bool]$isXP = $FALSE)  054$adsiPath = -f ($RDVHost -split "\\")  055if ((([ADSI]$adsiPath).Class -ne "Group") -AND ($vhost -notmatch '\$$'))  057$RDVHost = "$RDVHost$" 060$nameSpace = if ($isXP) {"root\cimv2"} else {"root\cimv2\terminalservices"}  062$tsAccounts = @(Get-WMIObject -Namespace $nameSpace -Query "SELECT * FROM Win32_TSAccount WHERE (TerminalName = 'RDP-TCP' OR TerminalName = 'Console') AND AccountName = '$($RDVHost.replace("\", "\\"))'")  064if ($tsAccounts -eq $NULL -or $tsaccounts.count -eq 0)  066Write-Log "  $RDVHost is being added to the RDP-TCP permissions list" "verbose" 068$permissionSettings = @(Get-WmiObject -Namespace $nameSpace -Query "SELECT * FROM Win32_TSPermissionsSetting WHERE TerminalName = 'RDP-TCP'")  070foreach($setting in $permissionSettings)  072$setting.addaccount("$RDVHost", 1) | Out-Null  073${script:restartRequired} = $TRUE  077$tsAccounts = @(Get-WMIObject -Namespace $nameSpace -Query "SELECT * FROM Win32_TSAccount WHERE (TerminalName = 'RDP-TCP' OR TerminalName = 'Console') AND AccountName = '$($RDVHost.replace("\", "\\"))'")  079foreach($account in $tsAccounts)  081if (($account.PermissionsAllowed -band 517) -ne 517)  083Write-Log "  Granting permissions : $RDVHost" "verbose" 085$account.ModifyPermissions(0,1) | Out-Null  086$account.ModifyPermissions(2,1) | Out-Null              087$account.ModifyPermissions(9,1) | Out-Null  089${script:restartRequired} = $TRUE  095function Configure-XP()  097#   1. Enable Remote Desktop.  099Write-Log "`n  Enabling Remote Desktop..." "verbose" 101$result = Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections -ErrorAction SilentlyContinue  103if ($result -eq $NULL)  105$result = New-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections -PropertyType DWORD -Value 0  107elseif ($result.AllowRemoteRPC -ne 1)  109$result = Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections -Value 0 -Passthru  110${script:restartRequired} = $TRUE  113if ($result.fDenyTSConnections -eq 0)  115Write-Log "    Done" "verbose" 119Write-Log "Remote Desktop could not be enabled" "error" 120$anyFailures = $TRUE  125#   2. Enable RPC.  127Write-Log "`n  Enabling RPC..." "verbose" 129$result = Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name AllowRemoteRpc -ErrorAction SilentlyContinue  131if ($result -eq $NULL)  133$result = New-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name AllowRemoteRPC -PropertyType DWORD -Value 1  135elseif ($result.AllowRemoteRPC -ne 1)  137$result = Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name AllowRemoteRpc -Value 1 -Passthru  138${script:restartRequired} = $TRUE  141if ($result.AllowRemoteRpc -eq 1)  143Write-Log "    Done" "verbose" 147Write-Log "Remote Desktop could not be enabled" "error" 148$anyFailures = $TRUE  152#   3. Add users to the Remote Desktop Users group.  154if (($RDUsers -ne $NULL) -AND ($RDUsers.Count -gt 0))  156Write-Log "`n  Adding users to Remote Desktop Users group..." "verbose" 158$RDUsers | foreach {   159net localgroup 'Remote Desktop Users' $_ /add 2> $Null > $Null  160if ($LASTEXITCODE -eq 1)  162Write-Log "      Failed to add user $_ to 'Remote Desktop Users' group..." "error" 166Write-Log "    Done" "verbose" 171#   4. Grant RD Virtualization Host servers permissions in the RDP-TCP listener.  173Write-Log "`n  Granting RD Virtualization Host server RDP-TCP permissions..." "verbose" 175$RDVHost | %{Grant-RDPPermissions $_ $TRUE}  177Write-Log "    Done" "verbose" 181#   5. Enable Windows Firewall to allow an exception for Remote Desktop.  183Write-Log "`n  Enabling firewall for 'remote desktop'..." "verbose" 185netsh firewall set service type=REMOTEDESKTOP mode=ENABLE profile=ALL 2> $Null > $Null  186if ($LASTEXITCODE -eq 0)  188Write-Log "    Done" "verbose" 192Write-Log "Firewall could not be enabled for 'remote desktop'" "error" 193$anyFailures = $TRUE  198#   6. Enable Windows Firewall to allow an exception for Remote Service Management.  200Write-Log "  Enabling firewall for 'remote service management'..." "verbose" 202netsh firewall set service remoteadmin enable subnet 2> $Null > $Null  203if ($LASTEXITCODE -eq 0)  205Write-Log "  Done" "verbose" 209Write-Log "Firewall could not be enabled for 'remote service management'" "error" 210$anyFailures = $TRUE  215#   7. Restart the Remote Desktop Services service.  217if ((-not $DoNotRestartService) -AND (${script:restartRequired}))  219Write-Log "Rebooting machine..." "verbose" 221shutdown /r /t 10  226function Configure-PostXP()  228#   1. Enable Remote Desktop.  230Write-Log "`n  Enabling Remote Desktop..." "verbose" 232$result = Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections -ErrorAction SilentlyContinue  234if ($result -eq $NULL)  236$result = New-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections -PropertyType DWORD -Value 0  238elseif ($result.AllowRemoteRPC -ne 1)  240$result = Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections -Value 0 -Passthru  241${script:restartRequired} = $TRUE  244if ($result.fDenyTSConnections -eq 0)  246Write-Log "    Done" "verbose" 250Write-Log "Remote Desktop could not be enabled" "error" 251$anyFailures = $TRUE  256#   2. Enable RPC.  258Write-Log "`n  Enabling RPC..." "verbose" 260$result = Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name AllowRemoteRpc -ErrorAction SilentlyContinue  262if ($result -eq $NULL)  264$result = New-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name AllowRemoteRPC -PropertyType DWORD -Value 1  266elseif ($result.AllowRemoteRPC -ne 1)  268$result = Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name AllowRemoteRpc -Value 1 -Passthru  269${script:restartRequired} = $TRUE  272if ($result.AllowRemoteRpc -eq 1)  274Write-Log "    Done" "verbose" 278Write-Log "Remote Desktop could not be enabled" "error" 279$anyFailures = $TRUE  283#   3. Add Users to the Remote Desktop Users group.  285if (($RDUsers -ne $NULL) -AND ($RDUsers.Count -gt 0))  287Write-Log "`n  Adding users to the Remote Desktop Users group..." "verbose" 289$RDUsers | foreach {   290net localgroup 'Remote Desktop Users' $_ /add 2> $Null > $Null  291if ($LASTEXITCODE -eq 1)  293Write-Log "      Failed to add user $_ to the Remote Desktop Users group..." "error" 297Write-Log "    Done" "verbose" 302#   4. Grant RD Virtualization Host servers permissions in the RDP-TCP listener.  304Write-Log "`n  Granting RD Virtualization hosts RDP-TCP listener permissions..." "verbose" 306$RDVHost | %{Grant-RDPPermissions $_}  308Write-Log "    Done" "verbose" 312#   5. Enable Windows Firewall to allow an exception for Remote Desktop.  314Write-Log "`n  Enabling firewall for 'remote desktop'..." "verbose" 316netsh advfirewall firewall set rule group="remote desktop" new enable=yes 2> $Null > $Null  317if ($LASTEXITCODE -eq 0)  319Write-Log "    Done" "verbose" 323Write-Log "Firewall could not be enabled for 'remote desktop'" "error" 324$anyFailures = $TRUE  329#   6. Enable Windows Firewall to allow an exception for Remote Service Management.  331Write-Log "  Enabling firewall for 'remote service management'..." "verbose" 333netsh advfirewall firewall set rule group="remote service management" new enable=yes 2> $Null > $Null  334if ($LASTEXITCODE -eq 0)  336Write-Log "  Done" "verbose" 340Write-Log "Firewall could not be enabled for 'remote service management'" "error" 341$anyFailures = $TRUE  346#   7. Restart the Remote Desktop Services service.  348if ((-not $DoNotRestartService) -AND (${script:restartRequired}))  350Write-Log "Restarting the Remote Desktop Services service..." "verbose" 352$termService = Get-Service "TermService" 354Write-Log "  Stopping TermService..." "verbose" 355$termService.Stop()  356Start-Sleep 5  358Write-Log "  Starting TermService..." "verbose" 359$termService.Start()  360Start-Sleep 5  364function Test-ADObject ([string[]]$adEntries, [string[]]$Type)  366$toExit = $FALSE  367foreach($entry in $adEntries)  369$adsiPath = -f ($entry -split "\\")  372[ADSI]$adsiPath | Select-Object Name | Out-Null  376$throwError = !${script:Force}  378if ($Type -contains "Computer")  380$adsiPath = -f ($entry -split "\\")                  383[ADSI]$adsiPath | Select-Object Name | Out-Null  384$throwError = $FALSE  386catch { }  389if ($throwError)  391$toExit = $TRUE  392Write-Log "Existence of specified object '$entry' could not be verified. $($_.Exception.InnerException.Message.Trim())" "error" 394 397$adsiObj = [ADSI]$adsiPath  399if ($adsiObj.Name -eq $NULL)  401$toExit = $TRUE  402Write-Log "Specified object '$entry' does not exist" "error" 404elseif($Type -notcontains $adsiObj.Class)  406$toExit = $TRUE  407Write-Log "Specified object '$entry' is invalid. Specify an object of type $([string]::Join(" or ", $Type))" "error" 411if ($toExit)  413 417Write-Log "" "initialize" 418Check-Credentials  420Write-Log "Preparing virtual machine for the RD Virtualization Host server: " "verbose" 422Write-Log "  RDV Host  : $([string]::Join(", ", $RDVHost))" "verbose" 423Test-ADObject $RDVHost @("Computer", "Group")  425if ($RDUsers.Count -gt 0)  427Write-Log "  RD Users  : $([string]::Join(", ", $RDUsers))" "verbose" 428Test-ADObject $RDUsers @("User", "Group")  431$restartRequired = $FALSE  432$anyFailures = $FALSE  434$version = New-Object System.Version 6, 0, 0, 0  435if ([System.Environment]::OsVersion.Version -lt $version)  437Configure-XP  441Configure-PostXP  444if ($anyFailures)  446Write-Log "ERROR : There were one more errors preparing the virtual machine for the RD Virtualization Host server" "error" 450Write-Log "Virtual machine was prepared for use with the RD Virtualization Host server" "verbose" 451Write-Host "This virtual machine has been successfully configured for use with RD Virtualization." 如果要搭配自動化RemoteApp設定,會需要將RemoteApp的Config先匯出到NAS上,然後將下面這個PowerShell指派到User的Login Script內 這樣就可以自動去套RemoteApp的設定(需要自己寫一個Bat去套用wcx,如Install-RADCConnection.ps1 ) 001<#  002.SYNOPSIS  003Installs a connection in RemoteApp and Desktop Connections.  004.DESCRIPTION  005This script uses a RemoteApp and Desktop Connections bootstrap file(a .wcx file) to set up a connection in Windows 7 workstation. No user interaction is required.It sets up a connection only for the current user. Always run the script in the user's session.  007The necessary credentials must be available either as domain credentials or as cached credentials on the local machine. (You can use Cmdkey.exe to cache the credentials.)  009Error status information is saved in event log: (Applications and Services\Microsoft\Windows\RemoteApp and Desktop Connections).  011.Parameter WCXPath  012Specifies the path to the .wcx file  014.Example  016PS C:\> Install-RADCConnection.ps1 c:\test1\work_apps.wcx  018Installs the connection in RemoteApp and Desktop Connections using information  019in the specified .wcx file.  021#>  022Param(  023[parameter(Mandatory=$true,Position=0)]  024[string]  025$WCXPath  029function CheckForConnection  031Param (  032[parameter(Mandatory=$true,Position=0)]  033[string]  034 037[string] $connectionKey = "" 038[bool] $found = $false 040foreach ($connectionKey in get-item 'HKCU:\Software\Microsoft\Workspaces\Feeds\*' 2> $null)   043if ( ($connectionKey | Get-ItemProperty -Name URL).URL -eq $URL)  045$found = $true 050return $found  054# Process the bootstrap file  055[string] $wcxExpanded = [System.Environment]::ExpandEnvironmentVariables($WCXPath)   056[object[]] $wcxPathResults = @(Get-Item $wcxExpanded 2> $null)  058if ($wcxPathResults.Count -eq 0)  060Write-Host @"  062The .wcx file could not be found.  066exit(1)  069if ($wcxPathResults.Count -gt 1)  071Write-Host @"  073Please specify a single .wcx file.  077exit(1)  080[string] $wcxFile = $wcxPathResults[0].FullName  081[xml] $wcxXml = [string]::Join("", (Get-Content -LiteralPath $wcxFile))   082[string] $connectionUrl = $wcxXml.workspace.defaultFeed.url  084if (-not $connectionUrl)  086Write-Host @"  088The .wcx file is not valid.  092exit(1)  095if ((CheckForConnection $connectionUrl))  097Write-Host @"  099The connection in RemoteApp and Desktop Connections already exists.  103exit(1)  106Start-Process -FilePath rundll32.exe -ArgumentList 'tsworkspace,WorkspaceSilentSetup',$wcxFile -NoNewWindow -Wait  108# check for the Connection in the registry  109if ((CheckForConnection $connectionUrl))  111Write-Host @"  113Connection setup succeeded.  119Write-Host @"  121Connection setup failed.  123Consult the event log for failure information:  124(Applications and Services\Microsoft\Windows\RemoteApp and Desktop Connections).  128exit(1)  當測試都OK,也確定可以正常建立VM並指派到Pool中之後 您將第一個PowerShell放入排程中連續執行就可以了,只要一偵測到VM Session不夠,就會建立VM指派到Pools中 其實說穿了,概念很簡單,只是先讓Win7具有自動加入網域,相關的設定都先透過GPO設定好 然後TS PowerShell透過VMM取得全部VM的資訊,取得VDI VM的總數量,然後Monitor Online的Session取得一個Session比例值 透過相同的Hostname前置名稱,後面帶流水號,這樣就不會有重複名稱的問題 當建立完VM,同時製作一個Assin.txt給RDCB,等整個建立過程都完成後,透過WinRM給RDCB下指令去Assin這些VM到Pool內 這是整體運作上的概念,實際運行上其實還有些考量點,像是Memory、Network、CPU、GPU等 這篇只是分享給大家參考,因為Microsoft並沒有自動Assin VM到Pool的機制存在,也歡迎大家透過部落格跟我討論:P

上一篇:Hyper-V Guest OS啟用Jumbo Frame-使用Windows Server 2012 Beta 測試
下一篇:EXTJS] 下载文件错误 BADRESPONSE: illegal character

相关文章

相关评论