2016-08-17 7 views
0

최근에 필자가 읽은 내용과 이후에 본 비디오에서 PowerShell 스크립팅에 대해 가르치기 시작했습니다. PowerShell의 모든 기능을 GUI와 비교했습니다. 이것은 Windows 10 클라이언트와 서버 모두에 적용됩니다.PS VM 스크립트 : CSV 파일에서 Add-VMNetworkAdapter에 대한 인수를 확인하는 중 오류가 발생했습니다.

저는 Hyper-V를 실제로 사용하기 때문에 가정에서 Windows 10 Professional을 사용하고 있습니다.

내가 지금까지 내 스크립트가 무엇 :

Start-Job 
{ 
# Create new VMs based on the names given in the "VMName.csv" file. 

$NewVM = Import-Csv "D:\Hyper-V\Hyper_V_Scripts\Test_Gen2_Virtual_Machine_Scratch.csv" 

# Specifies VMName and Generation Number without attaching VHDX files. 

$NewVM | ForEach-Object {New-VM -Name $_.VMName -Generation $_.Generation -NoVHD} 

# Sets Startup, Mininum, and Maximum Memory fields. 

$NewVM | ForEach-Object {Set-VMMemory -VMName $_.VMName -StartupBytes 1GB -MinimumBytes 512MB -MaximumBytes $_.MaxMemory} 

# Creates VHDX file based on the VM name. 

$NewVM | ForEach-Object {New-VHD -Path ("F:\Hyper-v_Storage\"+$_.VMName+".vhdx") -SizeBytes $_.VHDXSize} 

# Adds VHDX to VMs. 

$NewVM | ForEach-Object {Add-VMHardDiskDrive -VMName $_.VMName -Path ("F:\Hyper-V_Storage\"+$_.VMName+".vhdx") -ControllerNumber 0 -ControllerLocation 0} 

# Add VMDVDDrive with ISO to VMs. 

$NewVM | ForEach-Object {Add-VMDvdDrive -VMName $_.VMName -Path ("D:\iso\"+$_.ISO+".iso") -ControllerNumber 0 -ControllerLocation 1} 

# Change firmware's boot order to CD/DVD, Hard Disk Drive, and Network Adapter 

$NewVM | ForEach-Object {Set-VMFirmware -VMName $_.VMName -BootOrder (Get-VM -Name $_.VMName | Get-VMDvdDrive),(Get-VM -Name $_.VMName | Get-VMHardDiskDrive),(Get-VM -Name $_.VMName | Get-VMNetworkAdapter)} 

# Add RemoteFX3DAdapter to certain VMs 

$NewVM | Where-Object {$_.VMName -like "Chief_Architect - Windows 10"} | ForEach-Object {Add-VMRemoteFx3dVideoAdapter -VMName $_.VMName} 

# Creates External Network Switch 

# New-VMSwitch "External Realtek NIC" -NetAdapterName "Realtek_NIC" -AllowManagementOS $False 

# Adds External Realtek_NIC to all VMs 


$NewVM | ForEach-Object {Add-VMNetworkAdapter -VMName $_.VMName -SwitchName "External Realtek NIC" -Name "External Realtek"} 
} 

내가 알고 싶습니다, 내가에만 필요한 점을 감안, "# 외부 스위치를 작성합니다"의 구성 요소를 할 것이 현명하다 한 번 해보시겠습니까? 아니면 한 번 실행해야하므로 별도로 실행해야합니까? 또한

는 "모든 VM에 #을 추가 외부 Realtek_NIC"에서 내가 마지막 줄을 실행할 때마다, 나는 다음과 같은 오류를 얻을 : 나는 그 오류 때 얻을 이유

Add-VMNetworkAdapter : Cannot validate argument on parameter 'VMName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. 
At line:1 char:55 
+ $NewVM | ForEach-Object {Add-VMNetworkAdapter -VMName $_.VMName} 
+              ~~~~~~~~~ 
    + CategoryInfo   : InvalidData: (:) [Add-VMNetworkAdapter], ParameterBindingValidationException 
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.HyperV.PowerShell.Commands.AddVMNetworkAdapter 

이해가 안 돼요 내가 만든 CSV 파일은 다른 모든 장소에서 잘 작동합니다. CSV 파일의

내용 : 제공하는 도움을 고급에서

VMName,MaxMemory,ISO,VHDXSize,Generation 
ADDS-DHCP-DNS-WDS - Windows Server 2016 TP 5,2147483648,TP_5\Windows_Server_2016\14300.1000.160324-1723.RS1_RELEASE_SVC_SERVER_OEMRET_X64FRE_EN-US,107374182400,2 
Chief_Architect - Windows 10,6442450944,Win10_1607_English_x64,37580963840,2 
Development - Windows 10,4294967296,Win10_1607_English_x64,161061273600,2 
PFSense,1073741824,pfSense-CE-2.3.1-RELEASE-amd64,2147483648,2 
Steam - Windows 10,6442450944,Win10_1607_English_x64,322122547200,2 
Storage Pool - Windows Server 2016 TP 5,2147483648,TP_5\Windows_Server_2016\14300.1000.160324-1723.RS1_RELEASE_SVC_SERVER_OEMRET_X64FRE_EN-US,42949672960,2 
Winixhub - Windows 10,4294967296,Win10_1607_English_x64,53687091200,2 
Winixhub Web Server - Windows Server 2016 TP 5,4294967296,TP_5\Windows_Server_2016\14300.1000.160324-1723.RS1_RELEASE_SVC_SERVER_OEMRET_X64FRE_EN-US,85899345920,2 

감사합니다. 정말 감사. :)

+0

Q on style : 왜'$ NewVM | ForEach-Object {...}'여러 번, 각 명령마다 한 번? 더 쉽고, 빠르며, 더 중요한 것은 더 나은 스타일이 아니겠습니까? 한 번만 반복하고 각 반복마다 해당 반복의 VM에서 모든 명령을 실행하십시오. –

+0

... 붙여 넣기 한 CSV에 실제 줄 사이에 빈 줄이 있습니다. CSV에는 헤더의 1 줄 (선택 사항)이 있고 파일의 각 레코드에 대해 1 줄이있는 것으로 가정합니다. 그것은 당신이 당신의 명령에 실제로 먹이고있는 것입니까? 그렇다면 모든 가져온 변수는 다른 모든 행에서 null/empty가되며 훨씬 이전에 오류가 발생하지 않은 것은 당연한 일입니다 ... 이는 붙여 넣기 중 사고 일 뿐이라고 생각하게합니다. 후자의 설명은 PS 스크립트가 동일한 문제점을 갖는 방법으로 증명 될 수 있습니다. –

+0

예, 붙여 넣기 중에 실수였습니다. 두 번째 게시물에서 제안한 내용에 맞게 모양/스타일을 개선 할 것을 권해주십시오. – KennethWC

답변

1

좋아, 나는 귀하의 의견을 지키면서 $NewVM을 통해 모든 여러 루프를 하나의 루프로 결합했습니다 (그리고 그 루프가 나오기 전에 스위치 생성을 이동했지만 여전히 주석 처리되었습니다). 또한 GFX 명령을 If 문으로 변경하여 해당 명령을 지정된 VM에만 적용합니다. 마지막으로 귀하의 Add-VMNetworkAdapter 명령을 수정했습니다. 유효하지 않은 매개 변수가 설정되어있어 작동하지 않습니다. 당신이 볼 수 Get-Help Add-VMNetworkAdapter을 실행하면 파라미터 설정은 다음과 같습니다

Add-VMNetworkAdapter [-VMName] <string[]> [-CimSession <CimSession[]>] [-ComputerName <string[]>] [-Credential <pscredential[]>] [-SwitchName <string>] [-IsLegacy <bool>] 
[-Name <string>] [-DynamicMacAddress] [-StaticMacAddress <string>] [-Passthru] [-ResourcePoolName <string>] [-DeviceNaming {On | Off}] [-WhatIf] [-Confirm] [<CommonParameters>] 

Add-VMNetworkAdapter [-CimSession <CimSession[]>] [-ComputerName <string[]>] [-Credential <pscredential[]>] [-ManagementOS] [-SwitchName <string>] [-Name <string>] 
[-DynamicMacAddress] [-StaticMacAddress <string>] [-Passthru] [-DeviceNaming {On | Off}] [-WhatIf] [-Confirm] [<CommonParameters>] 

Add-VMNetworkAdapter [-VM] <VirtualMachine[]> [-SwitchName <string>] [-IsLegacy <bool>] [-Name <string>] [-DynamicMacAddress] [-StaticMacAddress <string>] [-Passthru] 
[-ResourcePoolName <string>] [-DeviceNaming {On | Off}] [-WhatIf] [-Confirm] [<CommonParameters>] 

당신은 마지막 세트에서 첫 세트에서 -VMName-SwitchName을 사용하려고했습니다. 방금 변수를 만들 때 VM을 캡처하도록 변경 한 다음 -VM 매개 변수로 사용했습니다. VM을 작성한 직후에이 명령을 이동하여 변수의 데이터가 원래 상태가되도록했습니다. 다음은 내가 결국에 끝난 결과입니다 :

# Create new VMs based on the names given in the "VMName.csv" file. 
$NewVM = Import-Csv "D:\Hyper-V\Hyper_V_Scripts\Test_Gen2_Virtual_Machine_Scratch.csv" 

# Creates External Network Switch 
# New-VMSwitch "External Realtek NIC" -NetAdapterName "Realtek_NIC" -AllowManagementOS $False 

$NewVM | ForEach-Object { 
    # Specifies VMName and Generation Number without attaching VHDX files. 
    $VM = New-VM -Name $_.VMName -Generation $_.Generation -NoVHD 

    # Adds External Realtek_NIC to all VMs 
    Add-VMNetworkAdapter -VM $VM -SwitchName "External Realtek NIC" -Name "External Realtek" 

    # Sets Startup, Mininum, and Maximum Memory fields. 
    $VMMem = Set-VMMemory -VMName $_.VMName -StartupBytes 1GB -MinimumBytes 512MB -MaximumBytes $_.MaxMemory 

    # Creates VHDX file based on the VM name. 
    $VHD = New-VHD -Path ("F:\Hyper-v_Storage\"+$_.VMName+".vhdx") -SizeBytes $_.VHDXSize 

    # Adds VHDX to VMs 
    $VMHD = Add-VMHardDiskDrive -VMName $_.VMName -Path ("F:\Hyper-V_Storage\"+$_.VMName+".vhdx") -ControllerNumber 0 -ControllerLocation 0 

    # Add VMDVDDrive with ISO to VMs. 
    $VMDVD = Add-VMDvdDrive -VMName $_.VMName -Path ("D:\iso\"+$_.ISO+".iso") -ControllerNumber 0 -ControllerLocation 1 

    # Change firmware's boot order to CD/DVD, Hard Disk Drive, and Network Adapter 
    Set-VMFirmware -VMName $_.VMName -BootOrder (Get-VM -Name $_.VMName | Get-VMDvdDrive),(Get-VM -Name $_.VMName | Get-VMHardDiskDrive),(Get-VM -Name $_.VMName | Get-VMNetworkAdapter) 

    # Add RemoteFX3DAdapter to certain VMs 
    If($_.VMName -like "Chief_Architect - Windows 10") {Add-VMRemoteFx3dVideoAdapter -VMName $_.VMName} 
} 
+0

필자는 스크립트를 수정했으며, 어댑터를 추가하는 것 외에는 모든 것이 작동합니다. 스크립트의 번역본을 실행했는데 부팅 순서를 제외하고는 모두 작동했습니다. – KennethWC

+0

아, 글쎄, 당신은 항상 그 라인에 원래 명령을 사용할 수 있습니다. 내 대답을 편집하여 원본을 해당 행에 사용합니다. 왜 실패 할 지 확신 할 수 없지만, 당신이 일하는 것이 쉬운 해결책이다. – TheMadTechnician