반응형

이전글

2023.02.25 - [ChatGPT] - ChatGPT. Copy-VHDX, New-VM Script 병합

2023.03.01 - [ChatGPT] - ChatGPT. Powershell 관리자 권한으로 실행하는 Script 제작

 

이전 글에서 완성된 스크립트는 다음과 같습니다.

# Check if script is running as Administrator
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    # Restart script as Administrator
    Start-Process powershell.exe "-File `"$PSCommandPath`"" -Verb RunAs
    exit
}


#Part 1: 정보 입력
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing


$VMName = Read-Host "Enter the name of the virtual machine"
$VMProcessorCount = Read-Host "Enter the number of processors"

$VHDXFolders = Get-ChildItem -Path "F:\sysprepVHD" -Directory
$VHDXFiles = @()


$MemoryOptions = @{
    "2 GB" = 2GB
    "4 GB" = 4GB
    "8 GB" = 8GB
    "10 GB" = 10GB
    "16 GB" = 16GB
    "32 GB" = 32GB
}

$form = New-Object System.Windows.Forms.Form
$form.Text = 'Select the amount of memory'
$form.Size = New-Object System.Drawing.Size(300, 200)
$form.StartPosition = 'CenterScreen'

$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(75, 120)
$okButton.Size = New-Object System.Drawing.Size(75, 23)
$okButton.Text = 'OK'
$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $okButton
$form.Controls.Add($okButton)

$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Point(150, 120)
$cancelButton.Size = New-Object System.Drawing.Size(75, 23)
$cancelButton.Text = 'Cancel'
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $cancelButton
$form.Controls.Add($cancelButton)

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10, 20)
$label.Size = New-Object System.Drawing.Size(280, 20)
$label.Text = 'Please select the amount of memory:'
$form.Controls.Add($label)

$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10, 40)
$listBox.Size = New-Object System.Drawing.Size(260, 20)
$listBox.Height = 80

[void] $listBox.Items.AddRange($MemoryOptions.Keys)

$form.Controls.Add($listBox)

$form.Topmost = $true

$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
    $SelectedMemory = $listBox.SelectedItem
    $VMMemoryStartupBytes = $MemoryOptions[$SelectedMemory]

    $Switches = Get-VMSwitch | Select-Object -Property Name
    $form = New-Object System.Windows.Forms.Form
    $form.Text = 'Select a virtual switch'
    $form.Size = New-Object System.Drawing.Size(300,200)
    $form.StartPosition = 'CenterScreen'

    $okButton = New-Object System.Windows.Forms.Button
    $okButton.Location = New-Object System.Drawing.Point(75, 120)
    $okButton.Size = New-Object System.Drawing.Size(75, 23)
    $okButton.Text = 'OK'
    $okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    $form.AcceptButton = $okButton
    $form.Controls.Add($okButton)

    $cancelButton = New-Object System.Windows.Forms.Button
    $cancelButton.Location = New-Object System.Drawing.Point(150, 120)
    $cancelButton.Size = New-Object System.Drawing.Size(75, 23)
    $cancelButton.Text = 'Cancel'
    $cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    $form.CancelButton = $cancelButton
    $form.Controls.Add($cancelButton)

    $label = New-Object System.Windows.Forms.Label
    $label.Location = New-Object System.Drawing.Point(10, 20)
    $label.Size = New-Object System.Drawing.Size(280, 20)
    $label.Text = 'Please select a virtual switch:'
    $form.Controls.Add($label)

    $listBox1 = New-Object System.Windows.Forms.ListBox
    $listBox1.Location = New-Object System.Drawing.Point(10, 40)
    $listBox1.Size = New-Object System.Drawing.Size(260, 20)
    $listBox1.Height = 80

    [void] $listBox1.Items.AddRange($Switches.Name)

    $form.Controls.Add($listBox1)

    $form.Topmost = $true

    $result = $form.ShowDialog()
    $SelectedSwitch = $listBox1.SelectedItem
}


#Part2 Copy VHDX

foreach ($Folder in $VHDXFolders) {
    $VHDXFiles += Get-ChildItem -Path $Folder.FullName -Filter *.vhdx
}

$VHDXFileNames = @()
foreach ($File in $VHDXFiles) {
    $VHDXFileNames += $File.Name
}

$form = New-Object System.Windows.Forms.Form
$form.Text = 'Select a VHDX file'
$form.Size = New-Object System.Drawing.Size(300, 200)
$form.StartPosition = 'CenterScreen'

$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(75, 120)
$okButton.Size = New-Object System.Drawing.Size(75, 23)
$okButton.Text = 'OK'
$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $okButton
$form.Controls.Add($okButton)

$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Point(150, 120)
$cancelButton.Size = New-Object System.Drawing.Size(75, 23)
$cancelButton.Text = 'Cancel'
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $cancelButton
$form.Controls.Add($cancelButton)

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10, 20)
$label.Size = New-Object System.Drawing.Size(280, 20)
$label.Text = 'Please select a VHDX file:'
$form.Controls.Add($label)

$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10, 40)
$listBox.Size = New-Object System.Drawing.Size(260, 20)
$listBox.Height = 80

[void] $listBox.Items.AddRange($VHDXFileNames)

$form.Controls.Add($listBox)

$form.Topmost = $true

$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
    $SelectedFile = $listBox.SelectedItem
    $SelectedFilePath = ($VHDXFiles | Where-Object { $_.Name -eq $SelectedFile }).FullName
    
    $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
    $SaveFileDialog.InitialDirectory = [Environment]::GetFolderPath("Desktop")
    $SaveFileDialog.Filter = "VHDX files (*.vhdx)|*.vhdx"
    $SaveFileDialog.FileName = $SelectedFile

    if ($SaveFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
        $NewFolderPath = [System.IO.Path]::GetDirectoryName($SaveFileDialog.FileName)
        $NewFileName = [System.IO.Path]::GetFileName($SaveFileDialog.FileName)

        if (!(Test-Path $NewFolderPath)) {
            New-Item -ItemType Directory -Path $NewFolderPath
        }

        $BufferSize = 1024 * 1024
        $Buffer = New-Object byte[] $BufferSize
        $SourceStream = [System.IO.File]::OpenRead($SelectedFilePath)
        $DestinationStream = [System.IO.File]::Create($NewFolderPath + "\" + $NewFileName)
        $BytesRead = 0
        $TotalBytes = [System.Math]::Min($SourceStream.Length, [System.Int64]::MaxValue)
        $BytesCopied = 0

        while (($BytesRead = $SourceStream.Read($Buffer, 0, $BufferSize)) -gt 0) {
            $DestinationStream.Write($Buffer, 0, $BytesRead)
            $BytesCopied += $BytesRead
            Write-Progress -Activity "Copying $SelectedFile" -PercentComplete ([System.Int32](100 * $BytesCopied / $TotalBytes))
        }

        $SourceStream.Close()
        $DestinationStream.Close()
    }
}


#Part 3: New-VM
$VHDLocation = Split-Path -Path $DestinationStream.Name 
$VHDs = $DestinationStream.Name 

if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
        
            New-VM -Name $VMName -MemoryStartupBytes $VMMemoryStartupBytes -Generation 2 -Path $VHDLocation -SwitchName $SelectedSwitch -VHDPath $VHDs
            Set-VM -Name $VMName -ProcessorCount $VMProcessorCount 
            Start-VM -Name $VMName
          
}

 

그런데 여기서 VHDX파일이 너무 많으면 스크롤을 내리면서 선택하는 것이 불편하다는 피드백을 받았습니다.

 

부분을 폴더 선택 -> 최종 VHDX 선택으로 변경을 시도해보겠습니다.

 

GPT에게 전체 스크립트를 분석 요청한 , 다음과 같이 질문하였습니다.


ChatGPT 답변

To modify Part 2 so that the script only displays the folders in F:\sysprep and allows the user to navigate to the VHDX file they want to use, you can replace the code block that populates the $VHDXFolders and $VHDXFileNames arrays with code that displays a folder browser dialog for the user to select a folder, and then displays a file dialog for the user to select the VHDX file.

Here's an example of how you can modify Part 2:

 

스크립트가 F:\sysprep의 폴더만 표시하고 사용자가 사용할 VHDX 파일을 탐색할 수 있도록 파트 2를 수정하려면 $VHDXFolders 및 $VHDXFileNames 배열에는 사용자가 폴더를 선택할 수 있는 폴더 브라우저 대화 상자를 표시한 다음 사용자가 VHDX를 선택할 수 있는 파일 대화 상자를 표시하는 코드가 포함됩니다.

다음은 파트 2를 수정하는 방법의 예입니다.

 

#Part 2: Copy VHDX

$folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
$folderBrowser.SelectedPath = "F:\sysprepVHD"
$folderBrowser.Description = "Select the folder containing the VHDX file"

if ($folderBrowser.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
    $VHDXFolder = $folderBrowser.SelectedPath

    $fileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $fileDialog.InitialDirectory = $VHDXFolder
    $fileDialog.Filter = "VHDX files (*.vhdx)|*.vhdx"
    $fileDialog.Title = "Select the VHDX file"
    
    if ($fileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
        $SelectedFilePath = $fileDialog.FileName
        
        $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
        $SaveFileDialog.InitialDirectory = [Environment]::GetFolderPath("Desktop")
        $SaveFileDialog.Filter = "VHDX files (*.vhdx)|*.vhdx"
        $SaveFileDialog.FileName = [System.IO.Path]::GetFileName($SelectedFilePath)

        if ($SaveFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
            $NewFolderPath = [System.IO.Path]::GetDirectoryName($SaveFileDialog.FileName)
            $NewFileName = [System.IO.Path]::GetFileName($SaveFileDialog.FileName)

            if (!(Test-Path $NewFolderPath)) {
                New-Item -ItemType Directory -Path $NewFolderPath
            }

            $BufferSize = 1024 * 1024
            $Buffer = New-Object byte[] $BufferSize
            $SourceStream = [System.IO.File]::OpenRead($SelectedFilePath)
            $DestinationStream = [System.IO.File]::Create($NewFolderPath + "\" + $NewFileName)
            $BytesRead = 0
            $TotalBytes = [System.Math]::Min($SourceStream.Length, [System.Int64]::MaxValue)
            $BytesCopied = 0

            while (($BytesRead = $SourceStream.Read($Buffer, 0, $BufferSize)) -gt 0) {
                $DestinationStream. Write($Buffer, 0, $BytesRead)
                $BytesCopied += $BytesRead
                Write-Progress -Activity "Copying $SelectedFile" -PercentComplete ([System.Int32](100 * $BytesCopied / $TotalBytes))
            }

            $SourceStream. Close()
            $DestinationStream. Close()
        }
    }
}

This modified code displays a folder browser dialog that allows the user to select a folder from F:\sysprep. Once a folder is selected, a file dialog is displayed that allows the user to select a VHDX file from the selected folder. The selected VHDX file is then copied to a new location using the save file dialog, just as in the original script.

 

Note that this code assumes that the user will only select a single VHDX file to use for the virtual machine. If you need to support the selection of multiple VHDX files, you'll need to modify the script accordingly.

 

이 수정된 코드는 사용자가 'F:\sysprep'에서 폴더를 선택할 수 있는 폴더 브라우저 대화 상자를 표시합니다. 폴더를 선택하면 사용자가 선택한 폴더에서 VHDX 파일을 선택할 수 있는 파일 대화 상자가 표시됩니다. 선택한 VHDX 파일은 원래 스크립트에서와 마찬가지로 파일 저장 대화 상자를 사용하여 새 위치로 복사됩니다.

 

이 코드는 사용자가 단일 VHDX 파일만 선택하여 가상 기기. 여러 VHDX 파일 선택을 지원해야 하는 경우 그에 따라 스크립트를 수정해야 합니다.


수정 스크립트를 실행하면 다음과 같이 나타납니다.

폴더 선택 -> 최종 경로에서 VHDX 파일이 보이는 형태는 아닙니다.

 

탐색기 창이 열리면서 선택을 하게 되고,

 

기존과 마찬가지로 복사를 위치를 선택하게 됩니다.

 

복사가 완료되면, VM 실행됩니다.

 

그런데 뭔가 아쉽습니다. 폴더를 확장하면서 VHDX 파일을 한번에 선택하면 좋을 같습니다.

아래의 화면에서 VHDX 끝까지 선택할 있도록 변경하거나

 

아니면 처음부터 아래의 화면이 나타나서 선택을 있는 구조로 바꿔야 같습니다.

 

FolderBrowserDialog 보다는

 

OpenFileDialog 형태로 바꾸는게 적합할 같습니다.

 

부분이 반영되도록 GPT에게 요청해보겠습니다.

청해보겠습니다.


ChatGPT 답변

Yes, you can modify the script to use an OpenFileDialog from the beginning to allow the user to select the VHDX file directly. Here's an example of how you can modify Part 2 to use an OpenFileDialog:

예, 사용자가 VHDX 파일을 직접 선택할 수 있도록 처음부터 OpenFileDialog를 사용하도록 스크립트를 수정할 수 있습니다. 다음은 OpenFileDialog를 사용하도록 파트 2를 수정하는 방법에 대한 예입니다.

#Part 2: Copy VHDX

$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.InitialDirectory = "F:\sysprepVHD"
$openFileDialog.Filter = "VHDX files (*.vhdx)|*.vhdx"
$openFileDialog.Title = "Select the VHDX file"

if ($openFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
    $SelectedFilePath = $openFileDialog.FileName
    
    $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
    $SaveFileDialog.InitialDirectory = [Environment]::GetFolderPath("Desktop")
    $SaveFileDialog.Filter = "VHDX files (*.vhdx)|*.vhdx"
    $SaveFileDialog.FileName = [System.IO.Path]::GetFileName($SelectedFilePath)

    if ($SaveFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
        $NewFolderPath = [System.IO.Path]::GetDirectoryName($SaveFileDialog.FileName)
        $NewFileName = [System.IO.Path]::GetFileName($SaveFileDialog.FileName)

        if (!(Test-Path $NewFolderPath)) {
            New-Item -ItemType Directory -Path $NewFolderPath
        }

        $BufferSize = 1024 * 1024
        $Buffer = New-Object byte[] $BufferSize
        $SourceStream = [System.IO.File]::OpenRead($SelectedFilePath)
        $DestinationStream = [System.IO.File]::Create($NewFolderPath + "\" + $NewFileName)
        $BytesRead = 0
        $TotalBytes = [System.Math]::Min($SourceStream.Length, [System.Int64]::MaxValue)
        $BytesCopied = 0

        while (($BytesRead = $SourceStream.Read($Buffer, 0, $BufferSize)) -gt 0) {
            $DestinationStream. Write($Buffer, 0, $BytesRead)
            $BytesCopied += $BytesRead
            Write-Progress -Activity "Copying $SelectedFile" -PercentComplete ([System.Int32](100 * $BytesCopied / $TotalBytes))
        }

        $SourceStream. Close()
        $DestinationStream. Close()
    }
}

This modified code uses an OpenFileDialog to allow the user to select a VHDX file directly. Once a file is selected, a save file dialog is displayed that allows the user to select a new location and name for the VHDX file, just as in the original script.

Note that this code assumes that the user will only select a single VHDX file to use for the virtual machine. If you need to support the selection of multiple VHDX files, you'll need to modify the script accordingly.

 

이 수정된 코드는 OpenFileDialog를 사용하여 사용자가 VHDX 파일을 직접 선택할 수 있도록 합니다. 파일을 선택하면 원본 스크립트에서와 마찬가지로 사용자가 VHDX 파일의 새 위치와 이름을 선택할 수 있는 파일 저장 대화 상자가 표시됩니다.

이 코드는 사용자가 가상 머신에 사용할 단일 VHDX 파일만 선택합니다. 여러 VHDX 파일 선택을 지원해야 하는 경우 그에 따라 스크립트를 수정해야 합니다.


OpenFileDialog 속성을 입력한 , 호출하는 구조로 변경되었습니다.

 

아래의 영역만 지정한 , 해당 영역만 실행합니다.

 

$openFileDialog에서 어떻게 속성이 지정되어 있는지 확인할 있습니다.

 

$openFileDialog.ShowDialog() 실행하면,

 

의도한대로 바로 호출되는 것을 있습니다.

 

그리고 VHDX 파일을 저장하는 위치도 자주 사용하는 위치로 변경해보겠습니다.

$savefiledialog.InitialDirectory D:\ 변경하였습니다.

 

동일한 방식으로 저장되는 것을 있습니다. 아래의 속성 값들을 보면 Open Save 속성의 차이도 있습니다.

 

최종본은 다음과 같습니다.

# Check if script is running as Administrator
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    # Restart script as Administrator
    Start-Process powershell.exe "-File `"$PSCommandPath`"" -Verb RunAs
    exit
}


#Part 1: 정보 입력
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing


$VMName = Read-Host "Enter the name of the virtual machine"
$VMProcessorCount = Read-Host "Enter the number of processors"


$MemoryOptions = [ordered]@{
    "2 GB" = 2GB
    "4 GB" = 4GB
    "8 GB" = 8GB
    "10 GB" = 10GB
    "16 GB" = 16GB
    "32 GB" = 32GB
}

$form = New-Object System.Windows.Forms.Form
$form.Text = 'Select the amount of memory'
$form.Size = New-Object System.Drawing.Size(300, 200)
$form.StartPosition = 'CenterScreen'

$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(75, 120)
$okButton.Size = New-Object System.Drawing.Size(75, 23)
$okButton.Text = 'OK'
$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $okButton
$form.Controls.Add($okButton)

$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Point(150, 120)
$cancelButton.Size = New-Object System.Drawing.Size(75, 23)
$cancelButton.Text = 'Cancel'
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $cancelButton
$form.Controls.Add($cancelButton)

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10, 20)
$label.Size = New-Object System.Drawing.Size(280, 20)
$label.Text = 'Please select the amount of memory:'
$form.Controls.Add($label)

$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10, 40)
$listBox.Size = New-Object System.Drawing.Size(260, 20)
$listBox.Height = 80

[void] $listBox.Items.AddRange($MemoryOptions.Keys)
$listBox.SelectedIndex = 0
$form.Add_Shown({ $listBox.Focus() })

$form.Controls.Add($listBox)

$form.Topmost = $true

$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
    $SelectedMemory = $listBox.SelectedItem
    $VMMemoryStartupBytes = $MemoryOptions[$SelectedMemory]

    $Switches = Get-VMSwitch | Select-Object -Property Name | Sort-Object -Property Name
    $form = New-Object System.Windows.Forms.Form
    $form.Text = 'Select a virtual switch'
    $form.Size = New-Object System.Drawing.Size(300,200)
    $form.StartPosition = 'CenterScreen'

    $okButton = New-Object System.Windows.Forms.Button
    $okButton.Location = New-Object System.Drawing.Point(75, 120)
    $okButton.Size = New-Object System.Drawing.Size(75, 23)
    $okButton.Text = 'OK'
    $okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    $form.AcceptButton = $okButton
    $form.Controls.Add($okButton)

    $cancelButton = New-Object System.Windows.Forms.Button
    $cancelButton.Location = New-Object System.Drawing.Point(150, 120)
    $cancelButton.Size = New-Object System.Drawing.Size(75, 23)
    $cancelButton.Text = 'Cancel'
    $cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    $form.CancelButton = $cancelButton
    $form.Controls.Add($cancelButton)

    $label = New-Object System.Windows.Forms.Label
    $label.Location = New-Object System.Drawing.Point(10, 20)
    $label.Size = New-Object System.Drawing.Size(280, 20)
    $label.Text = 'Please select a virtual switch:'
    $form.Controls.Add($label)

    $listBox1 = New-Object System.Windows.Forms.ListBox
    $listBox1.Location = New-Object System.Drawing.Point(10, 40)
    $listBox1.Size = New-Object System.Drawing.Size(260, 20)
    $listBox1.Height = 80
    
	# 정렬된 스위치를 리스트 박스에 추가
	[void] $listBox1.Items.AddRange(($Switches | ForEach-Object { $_.Name }))
    $listBox1.SelectedIndex = 0
	$form.Add_Shown({ $listBox1.Focus() })
    
    $form.Controls.Add($listBox1)

    $form.Topmost = $true

    $result = $form.ShowDialog()
    $SelectedSwitch = $listBox1.SelectedItem
}


#Part 2: Copy VHDX

$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.InitialDirectory = "F:\sysprepVHD\"
$openFileDialog.Filter = "VHDX files (*.vhdx)|*.vhdx"
$openFileDialog.Title = "Select the VHDX file"



if ($openFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
    $SelectedFilePath = $openFileDialog.FileName
    
    $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
    $SaveFileDialog.InitialDirectory = "D:\"
    $SaveFileDialog.Filter = "VHDX files (*.vhdx)|*.vhdx"
    $SaveFileDialog.FileName = [System.IO.Path]::GetFileName($SelectedFilePath)

    if ($SaveFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
        $NewFolderPath = [System.IO.Path]::GetDirectoryName($SaveFileDialog.FileName)
        $NewFileName = [System.IO.Path]::GetFileName($SaveFileDialog.FileName)

        if (!(Test-Path $NewFolderPath)) {
            New-Item -ItemType Directory -Path $NewFolderPath
        }

        $BufferSize = 1024 * 1024
        $Buffer = New-Object byte[] $BufferSize
        $SourceStream = [System.IO.File]::OpenRead($SelectedFilePath)
        $DestinationStream = [System.IO.File]::Create($NewFolderPath + "\" + $NewFileName)
        $BytesRead = 0
        $TotalBytes = [System.Math]::Min($SourceStream.Length, [System.Int64]::MaxValue)
        $BytesCopied = 0

        while (($BytesRead = $SourceStream.Read($Buffer, 0, $BufferSize)) -gt 0) {
            $DestinationStream. Write($Buffer, 0, $BytesRead)
            $BytesCopied += $BytesRead
            Write-Progress -Activity "Copying $SelectedFile" -PercentComplete ([System.Int32](100 * $BytesCopied / $TotalBytes))
        }

        $SourceStream. Close()
        $DestinationStream. Close()
    }
}



#Part 3: New-VM
$VHDLocation = Split-Path -Path $DestinationStream.Name 
$VHDs = $DestinationStream.Name 

if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
        
            New-VM -Name $VMName -MemoryStartupBytes $VMMemoryStartupBytes -Generation 2 -Path $VHDLocation -SwitchName $SelectedSwitch -VHDPath $VHDs
            Set-VM -Name $VMName -ProcessorCount $VMProcessorCount 
            Start-VM -Name $VMName
          
}

 

실행시 Machine Name, Core 지정

 

RAM 지정

 

Switch 지정

 

경로에서 VHDX 지정

 

VHDX 저장할 대상 경로 지정

 

복사 진행 (참고로 Powershell ISE 빠릅니다.)

 

VM생성 시작 확인

 

이번 포스팅에서 Open, Save Dialog 원리에 대해서 배울 있었습니다.

 

#3월 19일 수정사항

[ordered]@{ 를 추가하여 RAM 순서 정렬

# ...
# MemoryOptions definition
$MemoryOptions = [ordered]@{
    "2 GB" = 2GB
    "4 GB" = 4GB
    "8 GB" = 8GB
    "10 GB" = 10GB
    "16 GB" = 16GB
    "32 GB" = 32GB
}

# ...

# Add the ordered keys to the list box
[void] $listBox.Items.AddRange($MemoryOptions.Keys)

# ...

 

Sort-Object -Property Name 활용하여 스위치를 이름 정령

# ...
# 스위치 선택하는 메뉴
# ...

$Switches = Get-VMSwitch | Select-Object -Property Name | Sort-Object -Property Name

# ...

# 정렬된 스위치를 리스트 박스에 추가
[void] $listBox1.Items.AddRange(($Switches | ForEach-Object { $_.Name }))

# ...

 

키보드로 쉽게 선택할 수 있도록 첫째 항목이 선택되도록 Add_Shown, focus 사용

# ...
# Displaying the form to select the amount of memory
# ...

[void] $listBox.Items.AddRange($MemoryOptions.Keys)
$listBox.SelectedIndex = 0

$form.Add_Shown({ $listBox.Focus() })

# ...

# Displaying the form to select a virtual switch
# ...

[void] $listBox1.Items.AddRange(($Switches | ForEach-Object { $_.Name }))
$listBox1.SelectedIndex = 0

$form.Add_Shown({ $listBox1.Focus() })

# ...
반응형

+ Recent posts