克隆并将Hyper-V VM添加到域

时间:2017-06-08 13:45:30

标签: c# powershell clone hyper-v windows-server-2016

我有一个独立的(不是群集的,但在域中)安装了Hyper-V角色的Windows Server 2016。 我需要每天克隆虚拟机,所以我写了几个小东西"使用C#和PowerShell。

  1. VHD的并行副本

    public static void Main(string[] args) {
        var sourceFile = args[0];
        var distanationDir = args[1];
        int numOfCopies = Int32.Parse(args[2]);
    
        //var sourceFile = $@"C:\temp\123.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);
            }
        }
    }
    
  2. 第二步是使用此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
    }
    
  3. 最后我需要将他们加入域名,但我需要为该主机上的每个VM运行一些脚本并将其添加到域中。

2 个答案:

答案 0 :(得分:1)

由于您应该能够使用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,$passwor‌​d) 
Get-VM | ForEach-Object { Invoke-Command -VMName $_.name -ScriptBlock {Add-Computer -DomainName $using:domain -Credential $using:credentia}}

答案 1 :(得分:0)

这是一个解决方案: 在客户端和服务器上运行此命令(在克隆或复制VHD之前)

Enable-PSRemoting -Force
winrm set winrm/config/client '@{TrustedHosts="*"}'

从hyper-v Host运行之后(这只是为了添加一个VM,但你可以在主机上创建它的ForEach ip of vm)

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

这个有效!