{"id":263,"date":"2022-01-05T18:39:13","date_gmt":"2022-01-05T18:39:13","guid":{"rendered":"https:\/\/virtuallyanything.net\/?p=263"},"modified":"2023-05-15T18:45:37","modified_gmt":"2023-05-15T18:45:37","slug":"how-to-create-virtual-machines-from-csv-with-powercli-on-vmware","status":"publish","type":"post","link":"https:\/\/virtuallyanything.net\/index.php\/2022\/01\/05\/how-to-create-virtual-machines-from-csv-with-powercli-on-vmware\/","title":{"rendered":"How to create Virtual Machines from CSV with PowerCLI on VMware"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/blogs.vmware.com\/PowerCLI\/files\/2020\/10\/PowerCLI.png\" alt=\"\"\/><\/figure><\/div>\n\n\n<p>Whenever it&#8217;s possible I like to <strong>automate <\/strong>whatever I can to release myself for other activities and save a huge time that would be wasted on <strong>repeatable <\/strong>or <strong>time-consuming<\/strong> tasks.<\/p>\n\n\n\n<p>I have been using pieces of the following script for a long time, in a &#8220;manual automation&#8221; way, let&#8217;s say. Getting blocks and loops of scripts and creating and configuring virtual machines as needed.<\/p>\n\n\n\n<p>In the last month I put together in a way that can be shared, and even if you don&#8217;t have much experience with powershell, you can still make use of it. \ud83d\ude42<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Prerequisites<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading has-vivid-cyan-blue-color has-text-color\">Install PowerCLI Module<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Install-Module VMware.PowerCLI<\/code><\/pre>\n\n\n\n<p>The offline installation is available <a href=\"https:\/\/developer.vmware.com\/web\/tool\/vmware-powercli\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading has-vivid-cyan-blue-color has-text-color\">Virtual Machine Template<\/h3>\n\n\n\n<p>Create a virtual machine template to be used as a base image for the deployment. No special requirements here, create accordingly to your environment.<\/p>\n\n\n\n<h3 class=\"wp-block-heading has-vivid-cyan-blue-color has-text-color\">VM Customization Specifications<\/h3>\n\n\n\n<p>Create <strong>two <\/strong>virtual machine customization specifications on vCenter (<strong>Linux <\/strong>and <strong>Windows<\/strong>). The only requirement is to set <strong>DNS <\/strong>under network section for the <span style=\"text-decoration: underline;\">Linux<\/span>, otherwise you might have issues after the deployment within the guest os.<\/p>\n\n\n\n<h3 class=\"wp-block-heading has-vivid-cyan-blue-color has-text-color\">CSV File<\/h3>\n\n\n\n<p>That&#8217;s the source file with all virtual machine details. There must be certain columns with specific values. These values are shown below:<\/p>\n\n\n\n<ul>\n<li>Name<\/li>\n\n\n\n<li>vCPU<\/li>\n\n\n\n<li>vRAM<\/li>\n\n\n\n<li>vNetwork<\/li>\n\n\n\n<li>vDisk2 ..N<\/li>\n\n\n\n<li>IP<\/li>\n\n\n\n<li>Subnet<\/li>\n\n\n\n<li>Gateway<\/li>\n\n\n\n<li>Datastore<\/li>\n\n\n\n<li>VMFolder<\/li>\n\n\n\n<li>Specs<\/li>\n\n\n\n<li>Template<\/li>\n\n\n\n<li>Notes<\/li>\n\n\n\n<li>OSType<\/li>\n\n\n\n<li>Dns1<\/li>\n\n\n\n<li>Dns2<\/li>\n<\/ul>\n\n\n\n<p>You can download an example spreadsheet in the link below.<\/p>\n\n\n\n<div class=\"wp-block-file\"><a id=\"wp-block-file--media-2e0663f8-0c49-492e-93ce-43389df02bee\" href=\"https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/DeployVMs.csv\">DeployVMs.csv<\/a><a href=\"https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/DeployVMs.csv\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-2e0663f8-0c49-492e-93ce-43389df02bee\">Download<\/a><\/div>\n\n\n\n<p>Each line will be specific to a virtual machine. That&#8217;s how the loop will read and create\/configure accordingly.<\/p>\n\n\n\n<p><strong>vDisks <\/strong>columns can be increased as many required (vDisk2, vDisk3, vDisk4, etc.). For those VMs which doens&#8217;t use the additional disks, put &#8220;0&#8221; where not required. It starts at vDisk2 to be easily identified later, as <strong>vDisk1 <\/strong>will be the <strong>OSDisk <\/strong>from template. The vDisk format can be also changed, <strong>line 63 <\/strong>in the script.<\/p>\n\n\n\n<p>The <strong>OSType <\/strong>value should be either &#8220;<strong>Windows<\/strong>&#8221; or &#8220;<strong>Linux<\/strong>&#8220;, that&#8217;s just a condition in order to properly run the VM creation per <strong>GuestOS<\/strong>.<\/p>\n\n\n\n<p>Running the script it will always prompt for the <strong>CSV <\/strong>file, insert the full path location.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"568\" height=\"61\" src=\"https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/image-1.png\" alt=\"\" class=\"wp-image-311\" srcset=\"https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/image-1.png 568w, https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/image-1-300x32.png 300w\" sizes=\"(max-width: 568px) 100vw, 568px\" \/><\/figure><\/div>\n\n\n<p>The next step will prompt <strong>vCenter credentials<\/strong>, once confirmed it won&#8217;t be prompted again if you run the script on the same powershell session.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"529\" height=\"64\" src=\"https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/image-2.png\" alt=\"\" class=\"wp-image-312\" srcset=\"https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/image-2.png 529w, https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/image-2-300x36.png 300w\" sizes=\"(max-width: 529px) 100vw, 529px\" \/><\/figure><\/div>\n\n\n<p>The script then starts to read each value and deploy the VMs accordingly:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"307\" height=\"105\" src=\"https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/image-3.png\" alt=\"\" class=\"wp-image-313\" srcset=\"https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/image-3.png 307w, https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/image-3-300x103.png 300w\" sizes=\"(max-width: 307px) 100vw, 307px\" \/><\/figure><\/div>\n\n\n<p>After initial deployment, the script will configure the VMs, in that section custom settings are configured, like <strong>vCPU<\/strong>, <strong>vRAM<\/strong>, <strong>vNetwork<\/strong>, etc.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"301\" height=\"85\" src=\"https:\/\/virtuallyanything.net\/wp-content\/uploads\/2022\/01\/image-4.png\" alt=\"\" class=\"wp-image-314\"\/><\/figure><\/div>\n\n\n<p>At the end you should see a message of <strong>deployment complete <\/strong>and the VMs will be <strong>powered on<\/strong>, and probably customization specifications will be running. After that the virtual machines will be <strong>ready <\/strong>for use and <strong>fully customized<\/strong>.<\/p>\n\n\n\n<p>Check the full script below, save as *.ps1 and use <strong>Powershell ISE <\/strong>or <strong>Powershell <\/strong>to run.<\/p>\n\n\n\n<p>Enjoy \ud83d\ude42<\/p>\n\n\n\n<div class=\"is-layout-flow wp-block-group\"><div class=\"wp-block-group__inner-container\">\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"theme:powershell-ise font-size:11 striped:false marking:false ranges:false nums-toggle:false wrap-toggle:false scroll:true lang:ps decode:true \">&lt;#\n.SYNOPSIS\n\t\tCreate Virtual Machines from a CSV file\n.DESCRIPTION\n\t\tThe scripts create and configure virtual machines based on a CSV file\n                The VM is customized and powered on after deployment\n            \n.INSTRUCTIONS\n            Install the VMware PowerCLI Powershell Module (Install-Module VMware.PowerCLI, Internet Connection required)\n            Offline Install available on https:\/\/developer.vmware.com\/web\/tool\/vmware-powercli\n            -&gt; Create the CSV file based on the template provided and enter the required details\n            -&gt; Add new vDisks columns as required, the script will create vDisks accordingly\n                Put zero where vDisks are not required\n            -&gt; Validate if all proper values are correct on the spreadsheet:\n                - Specs: vCenter Customization Specifications Name\n                - OSType: Windows or Linux (Only for a condition in the script)\n                - Folder: If the folder name exists in 2 different locations, you might get errors. No spaces is also helpful.\n                All the rest is self-explanatory\n            -&gt; Create the Customization Specifications on vCenter Server\n                In Linux Specifications add the required DNS Servers in Network section\n                There's no specific setting to be configured in the Specifications\n                Recommend to create a new one specific for the PS Script, as some values will be overwritten everytime you run the script\n            -&gt; Change Disk Format in \"#.VM Configuration Details\" line 63, if required\n            -&gt; Save the spreadsheet as *.csv\n            -&gt; Run the script and enter the values as prompted\n            -&gt; The script also creates a transcript on users' Documents folder\n.AUTHOR\n\t\tRafael Moura @ VirtuallyAnything.net - Dec\/2021\n.VERSION\n\t\t1.0 (Dec\/2021)\n        1.1 (Fev\/2023)\n             Added command for the network card to start and stay connected at power on (Suggested\/Commented by Gab)\n#&gt;\n#.#.# Variables #.#.#\nWrite-Host \"- - Setting Variables - -\" -ForegroundColor Cyan\n#.CSV File\nWrite-Host \"CSV File\" -ForegroundColor Green\n$CSV = Read-Host -Prompt 'Enter the CSV File Path (i.e. D:\\Files\\MyVMs.csv)'\n$DeployVMs = Import-Csv $CSV\nWrite-Host \"vCenter Server Connection and Credentials\" -ForegroundColor Green\n#.vCenter Server Details\nIf($vCenterCreds -eq $null){\n    $vCenterConn = Read-Host -Prompt 'Enter the vCenter Server FQDN (i.e. vcs01.lab.vmw)'\n    $vCenterCreds = Get-Credential -Message (\"Enter the Credentials for vCenter Server \"+$vCenterConn)\n}\nelse{\n    Write-Host \"Credentials for $vCenterConn already acquired\" -ForegroundColor Green\n}\nWrite-Host \"Connecting to vCenter Server $vCenterConn\" -ForegroundColor Green\nSet-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false | Out-Null\nConnect-VIServer -Server $vCenterConn -Credential $vCenterCreds | Out-Null\n#.VM Configuration Details\n$DiskFormat = 'thin' # Options: Thin \/ Thick \/ EagerZeroedThick  \n#.--------------------------------------------------------------------------------------------------.#\n#. Don't change any value below .#\n#.--------------------------------------------------------------------------------------------------.#\n#.\nStart-Transcript\nWrite-Host \"::: Action Phase :::\" -ForegroundColor Green\nWrite-Host \"::: Virtual Machines Deployment in Progress :::\" -ForegroundColor Green\nStart-Sleep 2\n#.\nforeach($vm in $DeployVMs){\n    Write-host \"Deploying VM: \" -ForegroundColor Green -NoNewline; Write-Host $vm.Name -ForegroundColor Cyan; Write-Host \"IP Address: \"-ForegroundColor Green -NoNewline; Write-Host $vm.IP -ForegroundColor Cyan; Write-Host \"ESXi Host: \"-ForegroundColor Green -NoNewline; Write-Host $vm.ESXi -ForegroundColor Cyan; Write-Host \"Datastore: \"-ForegroundColor Green -NoNewline; Write-Host $vm.Datastore -ForegroundColor Cyan; Write-host \"VM Folder: \" -ForegroundColor Green -NoNewline; Write-Host $vm.VMFolder -ForegroundColor Cyan; Write-Host \"\";\n        If($vm.OSType -eq \"Windows\"){\n        Get-OSCustomizationSpec $vm.Specs -Server $vCenterConn | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $vm.IP -SubnetMask $vm.Subnet -DefaultGateway $vm.Gateway -Dns $vm.Dns1,$vm.Dns2 | Out-Null\n        }\n        else \n        {\n        Get-OSCustomizationSpec $vm.Specs -Server $vCenterConn | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $vm.IP -SubnetMask $vm.Subnet -DefaultGateway $vm.Gateway | Out-Null\n        }\n    Get-OSCustomizationSpec $vm.Specs -Server $vCenterConn | Set-OSCustomizationSpec -NamingScheme fixed -NamingPrefix $vm.Name | Out-Null\n    New-VM -Name $vm.Name -VMhost $vm.ESXi -Template $vm.Template -OSCustomizationSpec $vm.Specs -confirm:$false -Datastore $vm.Datastore -Location $vm.VMFolder -Notes $vm.Notes | Out-Null\n}\n#.\nforeach($vm in $DeployVMs){\n    $VMDisks = ($DeployVMs | Get-Member -MemberType All) | Where-Object {$_.Name -match 'vDisk'}\n    $VMCores = ($vm.vCPU\/2)\n    $VMPg = Get-VDPortgroup -Name $vm.vNetwork\n    Write-host \"Configuring VM: \" -ForegroundColor Green -NoNewline; Write-Host $vm.Name -ForegroundColor Cyan; Write-Host \"vCPU: \"-ForegroundColor Green -NoNewline; Write-Host $vm.vCPU -ForegroundColor Cyan; Write-Host \"vRAM: \"-ForegroundColor Green -NoNewline; Write-Host $vm.vRAM -ForegroundColor Cyan; Write-Host \"vNetwork: \"-ForegroundColor Green -NoNewline; Write-Host $vm.vNetwork -ForegroundColor Cyan; Write-Host \"\";\n    Get-VM $vm.Name | Set-VM -NumCPU $vm.vCPU -MemoryGB $vm.vRAM -CoresPerSocket $VMCores -Confirm:$false | Out-Null\n        foreach($vdisk in $VMDisks){\n            If($vm.($vdisk.Name) -ne '0'){\n            Get-VM $vm.Name | New-HardDisk -CapacityGB $vm.($vdisk.Name) -Datastore $vm.Datastore -StorageFormat $DiskFormat | Out-Null\n            }\n        }\n    Get-VM $vm.Name | Get-NetworkAdapter | Set-NetworkAdapter -Portgroup $VMPg -Confirm:$false | Out-Null\n\n    Get-VM $vm.Name | Get-NetworkAdapter -Name \"Network adapter 1\" |\nSet-NetworkAdapter -StartConnected:$true -Confirm:$false | Out-Null\n\n    Get-VM $vm.Name | Start-VM | Out-Null\n}\n#.\nWrite-Host \"::: Virtual Machines Deployment Complete :::\" -ForegroundColor Green\nStop-Transcript<\/pre><\/div>\n<\/div><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Whenever it&#8217;s possible I like to automate whatever I can to release myself for other activities and save a huge time that would be wasted&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/virtuallyanything.net\/index.php\/2022\/01\/05\/how-to-create-virtual-machines-from-csv-with-powercli-on-vmware\/\">Continue reading<span class=\"screen-reader-text\">How to create Virtual Machines from CSV with PowerCLI on VMware<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[15,11],"tags":[16,18],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/virtuallyanything.net\/index.php\/wp-json\/wp\/v2\/posts\/263"}],"collection":[{"href":"https:\/\/virtuallyanything.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/virtuallyanything.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/virtuallyanything.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/virtuallyanything.net\/index.php\/wp-json\/wp\/v2\/comments?post=263"}],"version-history":[{"count":59,"href":"https:\/\/virtuallyanything.net\/index.php\/wp-json\/wp\/v2\/posts\/263\/revisions"}],"predecessor-version":[{"id":349,"href":"https:\/\/virtuallyanything.net\/index.php\/wp-json\/wp\/v2\/posts\/263\/revisions\/349"}],"wp:attachment":[{"href":"https:\/\/virtuallyanything.net\/index.php\/wp-json\/wp\/v2\/media?parent=263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtuallyanything.net\/index.php\/wp-json\/wp\/v2\/categories?post=263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtuallyanything.net\/index.php\/wp-json\/wp\/v2\/tags?post=263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}