克隆 Hyper-V VM 并将其添加到域
Cloning and Adding Hyper-V VM to Domain
我有一个独立的(不是集群的,但在域中)Windows 安装了 Hyper-V 角色的 Server 2016。
我需要每天克隆 VM,所以我使用 C# 和 PowerShell 编写了一些小的 "things"。
VHD 的平行拷贝
public static void Main(string[] args) {
var sourceFile = args[0];
var distanationDir = args[1];
int numOfCopies = Int32.Parse(args[2]);
//var sourceFile = $@"C:\temp3.VHD";
//var distanationDir = $@"C:\temp\vhds\";
//int numOfCopies = 15;
StartJob(sourceFile, distanationDir, numOfCopies, random);
}
private static void StartJob(string sourcefile, string distanationdir, int numOfCopies, Random random) {
int count = 0;
Parallel.For(0, numOfCopies, i => {
Console.WriteLine("i = {0}, thread = {1}", i, Thread.CurrentThread.ManagedThreadId);
try {
string atrib = Path.GetExtension(sourcefile);
string guid = Guid.NewGuid().ToString("N");
var copyNew = Path.GetFileNameWithoutExtension(sourcefile) + guid + atrib;
File.Copy(sourcefile, Path.Combine(distanationdir + '\', copyNew));
Console.WriteLine(@"Started{copyNew}");
} catch (IOException copyError) {
Console.WriteLine(copyError.Message);
}
}
}
第二步是使用此 PowerShell 脚本创建 VM,该脚本使用现有 VHDX 创建 VM。
$from = 81
$howmany = 30
$files = Get-ChildItem -Path "E:\Hyper-v" -Filter *.vhdx
if ($files) {
Write-Host "variable is not null"
try {
$vmIndex = $from
for ($i = 0; $i -lt $howmany; $i++) {
Write-Host "Start "
New-Vm -Name "AUT-TA$vmIndex" -Path "E:\Hyper-v\Virtual Machines" -MemoryStartupBytes 4294967296 -VHDPath $files[$i].FullName -SwitchName "Broadcom NetXtreme Gigabit Ethernet #4 - Virtual Switch"
Write-Host "Vm created " + "AUT-TA$vmIndex"
$vmIndex++
Write-Host "End"
}
exit
} catch {
[System.Exception]"caught a system exception"
}
} else {
Write-Host "No such files"
exit
}
最后我需要将它们加入域,但我需要一些脚本,该脚本将为该主机上的每个虚拟机 运行 并将其添加到域中。
由于您应该能够使用 PowerShell Direct,因此您可以只获取要在其上执行的 VM,然后 Invoke-Command -VMName
Add-Computer
命令。您的评论暗示您要将密码保存在脚本中。请记住这对安全的影响。
$domain = "myDomain"
$password = "myPassword!" | ConvertTo-SecureString -asPlainText -Force
$username = "$domain\myUserAccount"
$credential = New-Object System.Management.Automation.PSCredential($username,$password)
Get-VM | ForEach-Object { Invoke-Command -VMName $_.name -ScriptBlock {Add-Computer -DomainName $using:domain -Credential $using:credentia}}
这是一个解决方案:
运行 在客户端和服务器上执行此命令(在克隆或复制 VHD 之前)
Enable-PSRemoting -Force
winrm set winrm/config/client '@{TrustedHosts="*"}'
之后 运行 来自 hyper-v Host 这个(这只用于添加一个 VM,但你可以为主机上的每个虚拟机 ip 创建它)
#Local Cred
$passwordLoc = "Password"
$usernameLoc = "localhost\Administrator"
$credentialsLoc = New-Object System.Management.Automation.PsCredential($usernameLoc, (ConvertTo-SecureString $passwordLoc -AsPlainText -Force))
$ses = New-PSSession 192.168.90.91 -Credential $credentialsLoc
##Domain Cred
$domain = "domain.com"
$password = "Password"
$username = "$domain\PowerUser"
$credentials = New-Object System.Management.Automation.PsCredential($username, (ConvertTo-SecureString $password -AsPlainText -Force))
Invoke-command -Session $ses -ScriptBlock {
Add-Computer -DomainName $using:domain -Credential $using:credentials -ErrorAction Stop
Rename-Computer -NewName "AUT-TA41" -DomainCredential $using:credentials -Force -ErrorAction Stop
Restart-Computer -ErrorAction Stop}
这很有效!
我有一个独立的(不是集群的,但在域中)Windows 安装了 Hyper-V 角色的 Server 2016。 我需要每天克隆 VM,所以我使用 C# 和 PowerShell 编写了一些小的 "things"。
VHD 的平行拷贝
public static void Main(string[] args) { var sourceFile = args[0]; var distanationDir = args[1]; int numOfCopies = Int32.Parse(args[2]); //var sourceFile = $@"C:\temp3.VHD"; //var distanationDir = $@"C:\temp\vhds\"; //int numOfCopies = 15; StartJob(sourceFile, distanationDir, numOfCopies, random); } private static void StartJob(string sourcefile, string distanationdir, int numOfCopies, Random random) { int count = 0; Parallel.For(0, numOfCopies, i => { Console.WriteLine("i = {0}, thread = {1}", i, Thread.CurrentThread.ManagedThreadId); try { string atrib = Path.GetExtension(sourcefile); string guid = Guid.NewGuid().ToString("N"); var copyNew = Path.GetFileNameWithoutExtension(sourcefile) + guid + atrib; File.Copy(sourcefile, Path.Combine(distanationdir + '\', copyNew)); Console.WriteLine(@"Started{copyNew}"); } catch (IOException copyError) { Console.WriteLine(copyError.Message); } } }
第二步是使用此 PowerShell 脚本创建 VM,该脚本使用现有 VHDX 创建 VM。
$from = 81 $howmany = 30 $files = Get-ChildItem -Path "E:\Hyper-v" -Filter *.vhdx if ($files) { Write-Host "variable is not null" try { $vmIndex = $from for ($i = 0; $i -lt $howmany; $i++) { Write-Host "Start " New-Vm -Name "AUT-TA$vmIndex" -Path "E:\Hyper-v\Virtual Machines" -MemoryStartupBytes 4294967296 -VHDPath $files[$i].FullName -SwitchName "Broadcom NetXtreme Gigabit Ethernet #4 - Virtual Switch" Write-Host "Vm created " + "AUT-TA$vmIndex" $vmIndex++ Write-Host "End" } exit } catch { [System.Exception]"caught a system exception" } } else { Write-Host "No such files" exit }
最后我需要将它们加入域,但我需要一些脚本,该脚本将为该主机上的每个虚拟机 运行 并将其添加到域中。
由于您应该能够使用 PowerShell Direct,因此您可以只获取要在其上执行的 VM,然后 Invoke-Command -VMName
Add-Computer
命令。您的评论暗示您要将密码保存在脚本中。请记住这对安全的影响。
$domain = "myDomain"
$password = "myPassword!" | ConvertTo-SecureString -asPlainText -Force
$username = "$domain\myUserAccount"
$credential = New-Object System.Management.Automation.PSCredential($username,$password)
Get-VM | ForEach-Object { Invoke-Command -VMName $_.name -ScriptBlock {Add-Computer -DomainName $using:domain -Credential $using:credentia}}
这是一个解决方案: 运行 在客户端和服务器上执行此命令(在克隆或复制 VHD 之前)
Enable-PSRemoting -Force
winrm set winrm/config/client '@{TrustedHosts="*"}'
之后 运行 来自 hyper-v Host 这个(这只用于添加一个 VM,但你可以为主机上的每个虚拟机 ip 创建它)
#Local Cred
$passwordLoc = "Password"
$usernameLoc = "localhost\Administrator"
$credentialsLoc = New-Object System.Management.Automation.PsCredential($usernameLoc, (ConvertTo-SecureString $passwordLoc -AsPlainText -Force))
$ses = New-PSSession 192.168.90.91 -Credential $credentialsLoc
##Domain Cred
$domain = "domain.com"
$password = "Password"
$username = "$domain\PowerUser"
$credentials = New-Object System.Management.Automation.PsCredential($username, (ConvertTo-SecureString $password -AsPlainText -Force))
Invoke-command -Session $ses -ScriptBlock {
Add-Computer -DomainName $using:domain -Credential $using:credentials -ErrorAction Stop
Rename-Computer -NewName "AUT-TA41" -DomainCredential $using:credentials -Force -ErrorAction Stop
Restart-Computer -ErrorAction Stop}
这很有效!