【问题标题】:Cloning and Adding Hyper-V VM to Domain克隆 Hyper-V 虚拟机并将其添加到域
【发布时间】:2017-11-10 06:31:40
【问题描述】:

我有一个安装了 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 运行并将其添加到域中。

【问题讨论】:

  • 有些人这样想 $domain = "myDomain" $password = "myPassword!" | ConvertTo-SecureString -asPlainText -Force $username = "$domain\myUserAccount" $credential = New-Object System.Management.Automation.PSCredential($username,$password) Add-Computer -DomainName $domain -Credential $credential 。但是有些人认为我可以在服务器 hyper-v 上运行并将所有 VM 添加到域中

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


【解决方案1】:

由于您应该能够使用 PowerShell Direct,因此您只需获取要在其上执行的 VM,然后使用 Invoke-Command -VMNameAdd-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}}

【讨论】:

  • 为以下参数提供值:出现 Windows PowerShell 无法处理的错误。远程会话可能已结束。 + CategoryInfo : OpenError: (AUT-TA100:String) [], PSRemotingDataStructureException + FullyQualifiedErrorId : PSSessionStateBroken 这是我收到的,每次我需要输入凭据时
  • @AndreyDzhezhora,您是否更改了 $domain$password$username 以反映您的域价值?如果是这样,它应该可以工作!
  • @FoxDeploy 肯定是的。
  • 也许我需要在虚拟机上做一些先决条件?运行一些命令?
【解决方案2】:

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

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

从 hyper-v 主机运行后(这仅用于添加一个虚拟机,但您可以在主机上创建它 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}

这行得通!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-18
    相关资源
    最近更新 更多