aplechaty's Posts

I just commented out those lines completely and it worked. Thank you for all the assistance. It is greatly appreciated.
  This is so frustrating but teh Tag is now working Thank you so very Much! Now suddenly for somereason I am getting the following. This didn't happen before updating what you sent me for the Tag. ... See more...
  This is so frustrating but teh Tag is now working Thank you so very Much! Now suddenly for somereason I am getting the following. This didn't happen before updating what you sent me for the Tag.   Get-OSCustomizationSpec : 7/21/2022 12:30:53 PM Get-OSCustomizationSpec Could not find Customization Specification with name 'Temp'. At C:\Users\adplechaty\PowerShell-Scripts\vCenter Server Deployment\7-24-2022_Deployment.ps1:314 char:13 + Get-OSCustomizationSpec -Name Temp | Remove-OSCustomizati ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Temp:String) [Get-OSCustomizationSpec], VimException + FullyQualifiedErrorId : Common_CommonUtil_FilterCollection_ObjectNotFound,VMware.VimAutomation.ViCore.Cmdlets.Co mmands.GetOSCustomizationSpec
Her are my tags in vCenter.
When i add what LucD suggested in his last post, i get the foolowing.   New-TagAssignment : 7/21/2022 12:00:20 PM New-TagAssignment com.vmware.vapi.std.errors.unauthenticated {'messages': [com.vmw... See more...
When i add what LucD suggested in his last post, i get the foolowing.   New-TagAssignment : 7/21/2022 12:00:20 PM New-TagAssignment com.vmware.vapi.std.errors.unauthenticated {'messages': [com.vmware.vapi.std.localizable_message {'id': com.vmware.vapi.endpoint.method.authentication.required, 'default_message': Authentication required., 'args': [], 'params': , 'localized':}], 'data': , 'error_type': UNAUTHENTICATED, 'challenge': Basic realm="VAPI endpoint",SIGN realm=6375ea75a6f71b1c60bdf03344aadb65017b2991,service="VAPI endpoint",sts="https://EXPVCENTER.quadax.net/sts/STSService/vsphere.local"} At C:\Users\adplechaty\PowerShell-Scripts\vCenter Server Deployment\7-24-2022_Deployment.ps1:325 char:13 + New-TagAssignment -Entity $vm -Tag $ChosenBackupTag + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [New-TagAssignment], CisException + FullyQualifiedErrorId : VMware.VimAutomation.ViCore.Impl.V1.Service.Tagging.Cis.TaggingServiceCisImpl.GetTag.Err or,VMware.VimAutomation.ViCore.Cmdlets.Commands.Tagging.NewTagAssignment New-TagAssignment : 7/21/2022 12:00:20 PM New-TagAssignment Could not find Tag with name 'DEV-4-Week-Windows'. At C:\Users\adplechaty\PowerShell-Scripts\vCenter Server Deployment\7-24-2022_Deployment.ps1:325 char:13 + New-TagAssignment -Entity $vm -Tag $ChosenBackupTag + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (DEV-4-Week-Windows:String) [New-TagAssignment], VimException + FullyQualifiedErrorId : Core_ObnSelector_SelectObjectByNameCore_ObjectNotFound,VMware.VimAutomation.ViCore.Cmdle ts.Commands.Tagging.NewTagAssignment New-TagAssignment : 7/21/2022 12:00:20 PM New-TagAssignment Value cannot be found for the mandatory parameter Tag At C:\Users\adplechaty\PowerShell-Scripts\vCenter Server Deployment\7-24-2022_Deployment.ps1:325 char:13 + New-TagAssignment -Entity $vm -Tag $ChosenBackupTag + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [New-TagAssignment], VimException + FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.Tagging.NewTag
OK here is the code I have the new tag commented.  For $Tag do I replace with $chosenBackupTag or the $BackupTag variable I am thinking the first.
Macleud I tried adding the $vm = in front of the New-Vm and it did not work. I have the script running error-free now but it still is not assigning the tag. due to my putting a # in front of the New-... See more...
Macleud I tried adding the $vm = in front of the New-Vm and it did not work. I have the script running error-free now but it still is not assigning the tag. due to my putting a # in front of the New-TagAssignment command since it was not working. if I can just get the Tag to assign now it would be perfect or close enough at least LOL.
Oops i also get all of the following as well, I did not in the past. WARNING: The 'Version' property of VirtualMachine type is deprecated. Use the 'HardwareVersion' property instead. PowerState... See more...
Oops i also get all of the following as well, I did not in the past. WARNING: The 'Version' property of VirtualMachine type is deprecated. Use the 'HardwareVersion' property instead. PowerState : PoweredOff Version : Unknown HardwareVersion : vmx-19 Notes : Guest : Testing: NumCpu : 2 CoresPerSocket : 2 MemoryMB : 6144 MemoryGB : 6 VMHostId : HostSystem-host-61 VMHost : myesx01.mydomain.net VApp : FolderId : Folder-group-v47 Folder : vm ResourcePoolId : ResourcePool-resgroup-56 ResourcePool : Resources PersistentId : 5025456a-4ac0-b3c3-79be-8cdb9a78816e UsedSpaceGB : 100.00173801742494106292724609 ProvisionedSpaceGB : 106.21403405629098415374755859 DatastoreIdList : {Datastore-datastore-125378} HARestartPriority : ClusterRestartPriority HAIsolationResponse : AsSpecifiedByCluster DrsAutomationLevel : AsSpecifiedByCluster VMSwapfilePolicy : Inherit VMResourceConfiguration : CpuShares:Normal/2000 MemShares:Normal/61440 GuestId : windows2019srvNext_64Guest CreateDate : 7/21/2022 2:12:19 PM SEVEnabled : False BootDelayMillisecond : 0 MigrationEncryption : Opportunistic MemoryHotAddEnabled : False MemoryHotAddIncrement : MemoryHotAddLimit : CpuHotAddEnabled : False CpuHotRemoveEnabled : False Name : Testing CustomFields : {[Business Division, ], [Created Date, ], [Creator, ], [Domain, ]...} ExtensionData : VMware.Vim.VirtualMachine Id : VirtualMachine-vm-139947 Uid : /VIServer=domain\myself@myvcenter.domain.net:443/VirtualMachine=VirtualMachine-vm-139947/
I think I am in the home stretch with LucD's awesome assistance however i added the line you gave me  New-TagAssignment -Entity $vm -Tag $tag   I get the following when I run the script, New-TagA... See more...
I think I am in the home stretch with LucD's awesome assistance however i added the line you gave me  New-TagAssignment -Entity $vm -Tag $tag   I get the following when I run the script, New-TagAssignment : Cannot bind argument to parameter 'Entity' because it is null. At C:\Users\adplechaty\PowerShell-Scripts\vCenter Server Deployment\7-23-2022_Deployment.ps1:331 char:39 + New-TagAssignment -Entity $vm -Tag $tag + ~~~ + CategoryInfo : InvalidData: (:) [New-TagAssignment], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,VMware.VimAutomation.ViCore.Cmdlets.Comma nds.Tagging.NewTagAssignment   Should I change $tag to my Variable which is $BackupTag or change it to $ChosenBackupTag? Also do I need to enter something different than $vm?  
Still getting same errors as the previous post.
Ugh I edited the script and added nettagassignment but now it is breaking higher up where it wasn't before. I attached the updated script. Thanks for the help by the way.   At C:\Users\myself\Pow... See more...
Ugh I edited the script and added nettagassignment but now it is breaking higher up where it wasn't before. I attached the updated script. Thanks for the help by the way.   At C:\Users\myself\PowerShell-Scripts\vCenter Server Deployment\VMDeployment.ps1:67 char:68 + ... .DESCRIPTION The function will retrieve a folder by it's path. + ~ Unexpected token 's' in expression or statement. At C:\Users\adplechaty\PowerShell-Scripts\vCenter Server Deployment\VMDeployment.ps1:115 char:13 + } + ~ Unexpected token '}' in expression or statement. + CategoryInfo : ParserError: (:) [], ParseException + FullyQualifiedErrorId : UnexpectedToken
Just to be clear do I remove the  | Out-Null from the command below and then add the New-Tag=Assignment on the next line or do i leave the | Out-Null?   New-VM -Name $ChosenName -Template $ChosenT... See more...
Just to be clear do I remove the  | Out-Null from the command below and then add the New-Tag=Assignment on the next line or do i leave the | Out-Null?   New-VM -Name $ChosenName -Template $ChosenTemplate -OSCustomizationSpec $ChosenCustomization -Datastore $ChosenDatastore -Location $ChosenFolder -NetworkName $ChosenNetwork -VMHost $ChosenHost -ResourcePool $ChosenCluster | Out-Null   New-TagAssignment -Entity $vm -Tag $BackupTag
I have attached the powershell script. Thanks in advance.
I added the script here yesterday but it is gone. I was hoping at the end of the script the tag could be assigned just not sure how to format the command to propagate the selected variable.
Here is the existing script. I added the Backup type variables just need to know if I can add the tag at some point so we don't have to do so after the fact.   #Variables     $VCenterServer = "my... See more...
Here is the existing script. I added the Backup type variables just need to know if I can add the tag at some point so we don't have to do so after the fact.   #Variables     $VCenterServer = "myvcenter.mydomain.net"     $Environments = "PROD","DEV"     $BusinessDivisions = "Corporate","DevOps","EA","ECM","EDI","Network Services","RCO","RCS"     $ServerFunctions = "Application","Web","Database","File","Management"     $DMZDomain = "domain.dmz"     $InternalDomain = "domain.net"     $DMZDNS = Resolve-DnsName -Type NS -Name $DMZDomain     $InternalDNS = Resolve-DnsName -Type NS -Name $InternalDomain         $IPPattern = "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"     $CurrentDate = Get-Date -Format d     $BackupTag = "DomainControllers","DEV-2-Week-Linux","DEV-2-Week-Windows","DEV-4-Week-Linux","DEV-4-Week-Windows","PROD-2-Week-Linux","PROD-2-Week-Windows",'PROD-4-Week-Linux","PROD-4-Week-Windows"     #Functions     #Quick function to give the user a prompt of specific options.         function Get-UserPrompt {             param (                 [Parameter(Mandatory=$true)]                 [string[]]$Options,                 [Parameter(Mandatory=$true)]                 [string]$Prompt                     )                         [int]$Response = 0;             [bool]$ValidResponse = $false                 while (!($ValidResponse)) {                             [int]$OptionNo = 0                 Write-Host $Prompt -ForegroundColor DarkYellow                 Write-Host "[0]: Cancel"                 foreach ($Option in $Options) {                     $OptionNo += 1                     Write-Host ("[$OptionNo]: {0}" -f $Option)                 }                 if ([Int]::TryParse((Read-Host), [ref]$Response)) {                     if ($Response -eq 0) {                         return ''                     }                     elseif($Response -le $OptionNo) {                         $ValidResponse = $true                     }                 }             }             return $Options.Get($Response - 1)         }         #Quick function to request specified information.         Function Get-DeploymentVariables{             param(                 [Parameter(Mandatory=$true)]                 [string]$Prompt                 )             Write-Host $Prompt -ForegroundColor DarkYellow             Read-Host         }         #Pull correct folder by specifying the path. Copied directly from: https://www.lucd.info/2012/05/18/folder-by-path/         function Get-FolderByPath{             <#             .SYNOPSIS Retrieve folders by giving a path             .DESCRIPTION The function will retrieve a folder by it's path.             The path can contain any type of leave (folder or datacenter).             .NOTES             Author: Luc Dekens .PARAMETER Path The path to the folder. This is a required parameter.             .PARAMETER             Path The path to the folder. This is a required parameter.             .PARAMETER             Separator The character that is used to separate the leaves in the path. The default is '/'             .EXAMPLE             PS> Get-FolderByPath -Path "Folder1/Datacenter/Folder2"             .EXAMPLE             PS> Get-FolderByPath -Path "Folder1>Folder2" -Separator '>'             #>                         param(             [CmdletBinding()]             [parameter(Mandatory = $true)]             [System.String[]]${Path},             [char]${Separator} = '/'             )                         process{                 if((Get-PowerCLIConfiguration).DefaultVIServerMode -eq "Multiple"){                 $vcs = $global:defaultVIServers                 }                 else{                 $vcs = $global:defaultVIServers[0]                 }                 $folders = @()                             foreach($vc in $vcs){                 $si = Get-View ServiceInstance -Server $vc                 $rootName = (Get-View -Id $si.Content.RootFolder -Property Name).Name                 foreach($strPath in $Path){                     $root = Get-Folder -Name $rootName -Server $vc -ErrorAction SilentlyContinue                     $strPath.Split($Separator) | ForEach-Object{                     $root = Get-Inventory -Name $_ -Location $root -NoRecursion -Server $vc -ErrorAction SilentlyContinue                     if((Get-Inventory -Location $root -NoRecursion | Select-Object -ExpandProperty Name) -contains "vm"){                         $root = Get-Inventory -Name "vm" -Location $root -Server $vc -NoRecursion                     }                     }                     $root | Where-Object {$_ -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.FolderImpl]}|ForEach-Object{                     $folders += Get-Folder -Name $_.Name -Location $root.Parent -NoRecursion -Server $vc                     }                 }                 }                 $folders             }             } #Connect to VCenter Server. Will prompt for credentials.     Connect-VIServer $VCenterServer #Prompts for all variables.     #PROD/DEV/QA/TEST.         $ChosenEnvironment = Get-UserPrompt -Options $Environments -Prompt "Choose Environment."         if($ChosenEnvironment -eq "PROD"){             $ChosenHost = Get-VMHost -Location "mydomain Production" | Sort-Object MemoryUsageGB -Descending | Select-Object -Last 1             $FolderPathStart = "mydomain Production/"             $ChosenCluster = Get-Cluster -Name "mydomain Production"         }         if($ChosenEnvironment -eq "DEV"){             $ChosenHost = Get-VMHost -Location "mydomain Development" | Sort-Object MemoryUsageGB -Descending | Select-Object -Last 1             $FolderPathStart = "mydomain Development/"             $ChosenCluster = "mydomain Development"             $ChosenCluster = Get-Cluster -Name "mydomain Development"         }     #Business Division         $ChosenDivision = Get-UserPrompt -Options $BusinessDivisions -Prompt "Choose Business Division."         #VM Notes         $ChosenNotes = Get-DeploymentVariables -Prompt "Enter VM Notes"     #Server Owner         $ChosenOwner = Get-DeploymentVariables -Prompt "Enter Server Owner"     #Server Function         $ChosenFunction = Get-UserPrompt -Options $ServerFunctions -Prompt "Choose Server Function"     #Creator         $ChosenCreator = Get-DeploymentVariables -Prompt "Enter Your Name"     #HD Event         $ChosenHDEvent = Get-DeploymentVariables -Prompt "Enter HD Event Number"         #Domain.         $ChosenDomain = Get-UserPrompt -Options ("DMZ","Internal") -Prompt "Choose Domain."     #OS.         $ChosenOS = Get-UserPrompt -Options ("2019","2022") -Prompt "Choose OS."         if($ChosenOS -eq "2019"){             $ChosenTemplate = Get-Template -Name "SRV2019_Template"         }         if($ChosenOS -eq "2022"){             $ChosenTemplate = Get-Template -Name "SRV2022_Template"         }     #Name.         $ChosenName = Get-DeploymentVariables -Prompt "Enter Server Name"     #Network. This may need to change when we switch to distributed switches.         $VMNetworks = Get-VirtualPortGroup | Sort-Object Name | Get-Unique         $ChosenNetwork = Get-UserPrompt -Options $VMNetworks -Prompt "Choose Network."                 Do{             $ChosenIP = Get-DeploymentVariables -Prompt "Enter IP Address."             $IPTest = $null             $IPTest = Test-Connection $ChosenIP -ErrorAction Ignore             $IPCheck = $ChosenIP -match $IPPattern             if($IPCheck -eq $true){                 if($null -ne $IPTest){                     Write-Host "IP is already in use. Try again." -ForegroundColor Red                 }}             if($IPCheck -eq $false) {                 Write-Host "Invalid IP address. Please try again." -ForegroundColor Red             }         }         Until ($null -eq $IPTest -and $IPCheck -eq $true)         Do{             $ChosenMask = $null             $ChosenMask = Get-DeploymentVariables -Prompt "Enter Subnet Mask."             $MaskCheck = $ChosenMask -match $IPPattern             If($MaskCheck -eq $false){                 Write-Host "Invalid Subnet Mask. Try again." -ForegroundColor Red             }         }         Until ($MaskCheck -eq $true)                 Do{             $ChosenGateway = $null             $ChosenGateway = Get-DeploymentVariables -Prompt "Enter Gateway."             $GatewayCheck = $ChosenGateway -match $IPPattern             If($GatewayCheck -eq $false){                 Write-Host "Invalid gateway, try again." -ForegroundColor Red             }         }         Until ($GatewayCheck -eq $true)     #Datastore.         if($ChosenEnvironment -eq "DEV"){             $Datastores = Get-DatastoreCluster -Location "mydomain Development" | Select-Object Name               $ChosenDatastore = Get-UserPrompt -Options $Datastores.Name -Prompt "Choose Datastore"         }         if($ChosenEnvironment -eq "PROD"){             $Datastores = Get-DatastoreCluster -Location "mydomain Production" | Select-Object Name               $ChosenDatastore = Get-UserPrompt -Options $Datastores.Name -Prompt "Choose Datastore"         }         #Socket count.         $ChosenSockets = Get-UserPrompt -Options ("2","4","6","8","10","12") -Prompt "Choose Number of Cores"     #Core count.         #$ChosenCores = Get-UserPrompt -Options ("2","3","4","5","6") -Prompt "Choose Number of Cores Per Socket"         $ChosenCores = $ChosenSockets/2     #Memory.         $ChosenMemory = Get-UserPrompt -Options ("6","8","10","12","14","16") -Prompt "Choose Memory GB"     #Update group.         $ADUpdateGroup = Get-ADGroup -Filter {Name -Like "*WSUS*" -and Name -NotLike "WSUSUpdates"} | Sort-Object Name         $ChosenUpdateGroup = Get-UserPrompt -Options $ADUpdateGroup.Name -Prompt "Choose Update Group" #Script     #Confirm chosen options are correct.         $Title = "Confirmation"         $Prompt = "Verify the following selections:         Environment - $ChosenEnvironment         Business Division - $ChosenDivision         Owner = $ChosenOwner         Server Function - $ChosenFunction         Notes - $ChosenNotes         Creator - $ChosenCreator         Helpdesk - $ChosenHDEvent         Creation Date - $CurrentDate         Domain - $ChosenDomain         OS - $ChosenOS         Name - $ChosenName         VM Network - $ChosenNetwork         IP Address - $ChosenIP         Subnet Mask - $ChosenMask         Gateway - $ChosenGateway         Datastore - $ChosenDatastore         Socket Count - $ChosenSockets         Core Count Per Socket - $ChosenCores         Memory - $ChosenMemory         Update Group - $ChosenUpdateGroup         `nAre you sure you want to continue?         `nYou will need to manually undo any changes that happen after this point."         $Choices = [System.Management.Automation.Host.ChoiceDescription[]] @("Yes", "Cancel")         $Default = 1         $Choice = $host.UI.PromptForChoice($Title, $Prompt, $Choices, $Default)         switch($Choice)             {                 0 {Write-Host "Continuing.                 Please Wait your Virtual Machine build is in progress! Once the cursosr has returned you can close this Powershell window and proceed to vCenter for any additional configuration!                 " -ForegroundColor Green}                 1 {Write-Host "Cancelling." -ForegroundColor Red                     Return}             }         #Deploy VM. Must program in wait for spin-up.         #Select OS Customization Spec             if($ChosenDomain -eq "DMZ"){                 $OSCustomization = Get-OSCustomizationSpec -Name "Server_2019/2022_Template_DMZ"                 $ChosenDNS = $DMZDNS             }             if($ChosenDomain -eq "Internal"){                 $OSCustomization = Get-OSCustomizationSpec -Name "Server_2019/2022_Template_NET"                 $ChosenDNS = $InternalDNS             }             Get-OSCustomizationSpec -Name Temp | Remove-OSCustomizationSpec -confirm:$false -ErrorAction Ignore | Out-Null             Get-OSCustomizationSpec -Name $OSCustomization | New-OSCustomizationSpec -Name Temp -Type NonPersistent | Set-OSCustomizationSpec -NamingScheme vm | Out-Null             Get-OSCustomizationSpec -Name Temp | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $ChosenIP -SubnetMask $ChosenMask -DefaultGateway $ChosenGateway -Dns $ChosenDNS.IP4Address | Out-Null             $ChosenCustomization = Get-OSCustomizationSpec -Name Temp                 #Select VM Cluster                   #Deploy VM             $FolderName = $FolderPathStart+"/"+$ChosenDivision             $ChosenFolder = Get-FolderByPath -Path  $FolderName             New-VM -Name $ChosenName -Template $ChosenTemplate -OSCustomizationSpec $ChosenCustomization -Datastore $ChosenDatastore -Location $ChosenFolder -NetworkName $ChosenNetwork -VMHost $ChosenHost -ResourcePool $ChosenCluster | Out-Null             Set-VM -VM $ChosenName -NumCpu $ChosenSockets -CoresPerSocket $ChosenCores -MemoryGB $ChosenMemory -Notes $ChosenNotes -Confirm:$false | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Environment" -Value $ChosenEnvironment | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Business Division" -Value $ChosenDivision| Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Created Date" -Value $CurrentDate | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Creator" -Value $ChosenCreator | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Domain" -Value $ChosenDomain | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Owner" -Value $ChosenOwner | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Server Function" -Value $ChosenFunction | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "HD Event" -Value $ChosenHDEvent | Out-Null             Start-VM -VM $ChosenName | Out-Null         #Ensure VM is ready to go.         #Options:             #Get-ADComputer returns a non-error. Requires unique name, which can be checked for and possibly deleted at beginning of script.             #Time delay.     #Modify Windows settings     #Update VMTools     #Update OS
Here is my script below, as you can see I added the Backup tag variable now I just need the proper command to assign the selected tag to the VM.  On a separate note, I am also getting an error on li... See more...
Here is my script below, as you can see I added the Backup tag variable now I just need the proper command to assign the selected tag to the VM.  On a separate note, I am also getting an error on line 130 which I have Italics below.   #Variables     $VCenterServer = "myvcenter.domain.net"     $Environments = "PROD","DEV"     $BusinessDivisions = "Corporate","DevOps","EA","ECM","EDI","Network Services","RCO","RCS"     $ServerFunctions = "Application","Web","Database","File","Management"     $DMZDomain = "domain.dmz"     $InternalDomain = "domain.net"     $DMZDNS = Resolve-DnsName -Type NS -Name $DMZDomain     $InternalDNS = Resolve-DnsName -Type NS -Name $InternalDomain         $IPPattern = "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"     $CurrentDate = Get-Date -Format d     $BackupTag = "DomainControllers","DEV-2-Week-Linux","DEV-2-Week-Windows","DEV-4-Week-Linux","DEV-4-Week-Windows","PROD-2-Week-Linux","PROD-2-Week-Windows",'PROD-4-Week-Linux","PROD-4-Week-Windows"     #Functions     #Quick function to give the user a prompt of specific options.         function Get-UserPrompt {             param (                 [Parameter(Mandatory=$true)]                 [string[]]$Options,                 [Parameter(Mandatory=$true)]                 [string]$Prompt                     )                         [int]$Response = 0;             [bool]$ValidResponse = $false                 while (!($ValidResponse)) {                             [int]$OptionNo = 0                 Write-Host $Prompt -ForegroundColor DarkYellow                 Write-Host "[0]: Cancel"                 foreach ($Option in $Options) {                     $OptionNo += 1                     Write-Host ("[$OptionNo]: {0}" -f $Option)                 }                 if ([Int]::TryParse((Read-Host), [ref]$Response)) {                     if ($Response -eq 0) {                         return ''                     }                     elseif($Response -le $OptionNo) {                         $ValidResponse = $true                     }                 }             }             return $Options.Get($Response - 1)         }         #Quick function to request specified information.         Function Get-DeploymentVariables{             param(                 [Parameter(Mandatory=$true)]                 [string]$Prompt                 )             Write-Host $Prompt -ForegroundColor DarkYellow             Read-Host         }         #Pull correct folder by specifying the path. Copied directly from: https://www.lucd.info/2012/05/18/folder-by-path/         function Get-FolderByPath{             <#             .SYNOPSIS Retrieve folders by giving a path             .DESCRIPTION The function will retrieve a folder by it's path.             The path can contain any type of leave (folder or datacenter).             .NOTES             Author: Luc Dekens .PARAMETER Path The path to the folder. This is a required parameter.             .PARAMETER             Path The path to the folder. This is a required parameter.             .PARAMETER             Separator The character that is used to separate the leaves in the path. The default is '/'             .EXAMPLE             PS> Get-FolderByPath -Path "Folder1/Datacenter/Folder2"             .EXAMPLE             PS> Get-FolderByPath -Path "Folder1>Folder2" -Separator '>'             #>                         param(             [CmdletBinding()]             [parameter(Mandatory = $true)]             [System.String[]]${Path},             [char]${Separator} = '/'             )                         process{                 if((Get-PowerCLIConfiguration).DefaultVIServerMode -eq "Multiple"){                 $vcs = $global:defaultVIServers                 }                 else{                 $vcs = $global:defaultVIServers[0]                 }                 $folders = @()                             foreach($vc in $vcs){                 $si = Get-View ServiceInstance -Server $vc                 $rootName = (Get-View -Id $si.Content.RootFolder -Property Name).Name                 foreach($strPath in $Path){                     $root = Get-Folder -Name $rootName -Server $vc -ErrorAction SilentlyContinue                     $strPath.Split($Separator) | ForEach-Object{                     $root = Get-Inventory -Name $_ -Location $root -NoRecursion -Server $vc -ErrorAction SilentlyContinue                     if((Get-Inventory -Location $root -NoRecursion | Select-Object -ExpandProperty Name) -contains "vm"){                         $root = Get-Inventory -Name "vm" -Location $root -Server $vc -NoRecursion                     }                     }                     $root | Where-Object {$_ -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.FolderImpl]}|ForEach-Object{                     $folders += Get-Folder -Name $_.Name -Location $root.Parent -NoRecursion -Server $vc                     }                 }                 }                 $folders             }             } #Connect to VCenter Server. Will prompt for credentials.     Connect-VIServer $VCenterServer #Prompts for all variables.     #PROD/DEV/QA/TEST.         $ChosenEnvironment = Get-UserPrompt -Options $Environments -Prompt "Choose Environment."         if($ChosenEnvironment -eq "PROD"){             $ChosenHost = Get-VMHost -Location "Expedient Production" | Sort-Object MemoryUsageGB -Descending | Select-Object -Last 1             $FolderPathStart = "Expedient Production/"             $ChosenCluster = Get-Cluster -Name "Expedient Production"         }         if($ChosenEnvironment -eq "DEV"){             $ChosenHost = Get-VMHost -Location "Expedient Development" | Sort-Object MemoryUsageGB -Descending | Select-Object -Last 1             $FolderPathStart = "Expedient Development/"             $ChosenCluster = "Expedient Development"             $ChosenCluster = Get-Cluster -Name "Expedient Development"         }     #Business Division         $ChosenDivision = Get-UserPrompt -Options $BusinessDivisions -Prompt "Choose Business Division."         #VM Notes         $ChosenNotes = Get-DeploymentVariables -Prompt "Enter VM Notes"     #Server Owner         $ChosenOwner = Get-DeploymentVariables -Prompt "Enter Server Owner"     #Server Function         $ChosenFunction = Get-UserPrompt -Options $ServerFunctions -Prompt "Choose Server Function"     #Creator         $ChosenCreator = Get-DeploymentVariables -Prompt "Enter Your Name"     #HD Event         $ChosenHDEvent = Get-DeploymentVariables -Prompt "Enter HD Event Number"         #Domain.         $ChosenDomain = Get-UserPrompt -Options ("DMZ","Internal") -Prompt "Choose Domain."     #OS.         $ChosenOS = Get-UserPrompt -Options ("2019","2022") -Prompt "Choose OS."         if($ChosenOS -eq "2019"){             $ChosenTemplate = Get-Template -Name "SRV2019_Template"         }         if($ChosenOS -eq "2022"){             $ChosenTemplate = Get-Template -Name "SRV2022_Template"         }     #Name.         $ChosenName = Get-DeploymentVariables -Prompt "Enter Server Name"     #Network. This may need to change when we switch to distributed switches.         $VMNetworks = Get-VirtualPortGroup | Sort-Object Name | Get-Unique         $ChosenNetwork = Get-UserPrompt -Options $VMNetworks -Prompt "Choose Network."                 Do{             $ChosenIP = Get-DeploymentVariables -Prompt "Enter IP Address."             $IPTest = $null             $IPTest = Test-Connection $ChosenIP -ErrorAction Ignore             $IPCheck = $ChosenIP -match $IPPattern             if($IPCheck -eq $true){                 if($null -ne $IPTest){                     Write-Host "IP is already in use. Try again." -ForegroundColor Red                 }}             if($IPCheck -eq $false) {                 Write-Host "Invalid IP address. Please try again." -ForegroundColor Red             }         }         Until ($null -eq $IPTest -and $IPCheck -eq $true)         Do{             $ChosenMask = $null             $ChosenMask = Get-DeploymentVariables -Prompt "Enter Subnet Mask."             $MaskCheck = $ChosenMask -match $IPPattern             If($MaskCheck -eq $false){                 Write-Host "Invalid Subnet Mask. Try again." -ForegroundColor Red             }         }         Until ($MaskCheck -eq $true)                 Do{             $ChosenGateway = $null             $ChosenGateway = Get-DeploymentVariables -Prompt "Enter Gateway."             $GatewayCheck = $ChosenGateway -match $IPPattern             If($GatewayCheck -eq $false){                 Write-Host "Invalid gateway, try again." -ForegroundColor Red             }         }         Until ($GatewayCheck -eq $true)     #Datastore.         if($ChosenEnvironment -eq "DEV"){             $Datastores = Get-DatastoreCluster -Location "Mydomain Development" | Select-Object Name               $ChosenDatastore = Get-UserPrompt -Options $Datastores.Name -Prompt "Choose Datastore"         }         if($ChosenEnvironment -eq "PROD"){             $Datastores = Get-DatastoreCluster -Location "Mydomain Production" | Select-Object Name               $ChosenDatastore = Get-UserPrompt -Options $Datastores.Name -Prompt "Choose Datastore"         }         #Socket count.         $ChosenSockets = Get-UserPrompt -Options ("2","4","6","8","10","12") -Prompt "Choose Number of Cores"     #Core count.         #$ChosenCores = Get-UserPrompt -Options ("2","3","4","5","6") -Prompt "Choose Number of Cores Per Socket"         $ChosenCores = $ChosenSockets/2     #Memory.         $ChosenMemory = Get-UserPrompt -Options ("6","8","10","12","14","16") -Prompt "Choose Memory GB"     #Update group.         $ADUpdateGroup = Get-ADGroup -Filter {Name -Like "*WSUS*" -and Name -NotLike "WSUSUpdates"} | Sort-Object Name         $ChosenUpdateGroup = Get-UserPrompt -Options $ADUpdateGroup.Name -Prompt "Choose Update Group" #Script     #Confirm chosen options are correct.         $Title = "Confirmation"         $Prompt = "Verify the following selections:         Environment - $ChosenEnvironment         Business Division - $ChosenDivision         Owner = $ChosenOwner         Server Function - $ChosenFunction         Notes - $ChosenNotes         Creator - $ChosenCreator         Helpdesk - $ChosenHDEvent         Creation Date - $CurrentDate         Domain - $ChosenDomain         OS - $ChosenOS         Name - $ChosenName         VM Network - $ChosenNetwork         IP Address - $ChosenIP         Subnet Mask - $ChosenMask         Gateway - $ChosenGateway         Datastore - $ChosenDatastore         Socket Count - $ChosenSockets         Core Count Per Socket - $ChosenCores         Memory - $ChosenMemory         Update Group - $ChosenUpdateGroup         `nAre you sure you want to continue?         `nYou will need to manually undo any changes that happen after this point."         $Choices = [System.Management.Automation.Host.ChoiceDescription[]] @("Yes", "Cancel")         $Default = 1         $Choice = $host.UI.PromptForChoice($Title, $Prompt, $Choices, $Default)         switch($Choice)             {                 0 {Write-Host "Continuing.                 Please Wait your Virtual Machine build is in progress! Once the cursosr has returned you can close this Powershell window and proceed to vCenter for any additional configuration!                 " -ForegroundColor Green}                 1 {Write-Host "Cancelling." -ForegroundColor Red                     Return}             }         #Deploy VM. Must program in wait for spin-up.         #Select OS Customization Spec             if($ChosenDomain -eq "DMZ"){                 $OSCustomization = Get-OSCustomizationSpec -Name "Server_2019/2022_Template_DMZ"                 $ChosenDNS = $DMZDNS             }             if($ChosenDomain -eq "Internal"){                 $OSCustomization = Get-OSCustomizationSpec -Name "Server_2019/2022_Template_NET"                 $ChosenDNS = $InternalDNS             }             Get-OSCustomizationSpec -Name Temp | Remove-OSCustomizationSpec -confirm:$false -ErrorAction Ignore | Out-Null             Get-OSCustomizationSpec -Name $OSCustomization | New-OSCustomizationSpec -Name Temp -Type NonPersistent | Set-OSCustomizationSpec -NamingScheme vm | Out-Null             Get-OSCustomizationSpec -Name Temp | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $ChosenIP -SubnetMask $ChosenMask -DefaultGateway $ChosenGateway -Dns $ChosenDNS.IP4Address | Out-Null             $ChosenCustomization = Get-OSCustomizationSpec -Name Temp                 #Select VM Cluster                   #Deploy VM             $FolderName = $FolderPathStart+"/"+$ChosenDivision             $ChosenFolder = Get-FolderByPath -Path  $FolderName             New-VM -Name $ChosenName -Template $ChosenTemplate -OSCustomizationSpec $ChosenCustomization -Datastore $ChosenDatastore -Location $ChosenFolder -NetworkName $ChosenNetwork -VMHost $ChosenHost -ResourcePool $ChosenCluster | Out-Null             Set-VM -VM $ChosenName -NumCpu $ChosenSockets -CoresPerSocket $ChosenCores -MemoryGB $ChosenMemory -Notes $ChosenNotes -Confirm:$false | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Environment" -Value $ChosenEnvironment | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Business Division" -Value $ChosenDivision| Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Created Date" -Value $CurrentDate | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Creator" -Value $ChosenCreator | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Domain" -Value $ChosenDomain | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Owner" -Value $ChosenOwner | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "Server Function" -Value $ChosenFunction | Out-Null             Set-Annotation -Entity $ChosenName -CustomAttribute "HD Event" -Value $ChosenHDEvent | Out-Null             Start-VM -VM $ChosenName | Out-Null         #Ensure VM is ready to go.         #Options:             #Get-ADComputer returns a non-error. Requires unique name, which can be checked for and possibly deleted at beginning of script.             #Time delay.     #Modify Windows settings     #Update VMTools     #Update OS
Thanks, I am looking for the exact string that would assign the tag selected. I'm not quite sure how to format the command using a pulled in variable? Also this script creates the Vm it doesn't alrea... See more...
Thanks, I am looking for the exact string that would assign the tag selected. I'm not quite sure how to format the command using a pulled in variable? Also this script creates the Vm it doesn't already exist so how do I add an entity that is yet to be created?  
I have a script currently for deploying virtual machines. What I am looking to do is prompt the user with a list of Tags to select from as follows. $Tags = "DEV-2-Week-Linux","DEV-4-Week-Linux","PRO... See more...
I have a script currently for deploying virtual machines. What I am looking to do is prompt the user with a list of Tags to select from as follows. $Tags = "DEV-2-Week-Linux","DEV-4-Week-Linux","PROD-2-Week-Linux","PROD-2-Week-Windows" So as the script runs I want the user to be prompted to select one of the tags. They make their selection and the script continues on. I then need the script at some point to assign the selected tag to the VM as it is created.    I am having a hard time figuring out how to actually set the tag on the newly created VM. Any help is greatly appreciated. Thanks in advance.