-1

I have Text file with number of local VM names in Hyper-v :

newname

IL-SRV

IL-TST

IL-MGN

IL-BBT

This is the names in my hyper-V environment , And i would like to change their computer name by using Powershell and bulk

I'm using this script

$computers = import-csv -Path C:\Users\Itay\Desktop\Servers.txt



foreach ($newname in $computers){

Invoke-Command -VMName $computers.newname -Credential administrator -ScriptBlock {Rename-Computer -NewName $computers.newname -Restart -Force}
}

But i receive this error

    "
Invoke-Command : The input VMName IL-SRV  does not resolve to a single virtual machine.
At line:11 char:1
+ Invoke-Command -VMName $computers.newname -Credential administrator - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Invoke-Command], ArgumentException
    + FullyQualifiedErrorId : InvalidVMNameNotSingle,Microsoft.PowerShell.Commands.InvokeCommandCommad
"
  • $computers.newname is the entire list you just imported. Plus, it seems you’re trying to rename them to the same name. Show a sample of your CSV. – Doug Maurer Aug 17 '20 at 18:44
  • No man I just installed them so they have generic name , it says there is no VM name IL-SRV but there is .. just the VM name in the Hyper v is IL-SRV and I want to change the computer name to same name as the VM Name .. –  Aug 17 '20 at 19:09

1 Answers1

0

Each iteration you are processing the entire list of $computers.newname

In your loop you create variable $newname without ever using it. You should be very careful when running commands that make changes especially if you aren't familiar with how powershell works. The other glaring issue is you are using Invoke-Command on a remote computer but using a local variable. I am taking a guess that you're trying to do is this.

$CSVData = import-csv -Path C:\Users\Itay\Desktop\Servers.txt

foreach ($line in $CSVData){

    Invoke-Command -VMName $line.newname -Credential administrator -ScriptBlock {Rename-Computer -NewName $using:line.newname -Restart -whatif}
}

Note the $using:line variable. This provides the contents of the local variable to the remote computer. Another way to handle it would be use the -Argumentlist. I recommend using named parameters when doing so, like this.

$CSVData = import-csv -Path C:\Users\Itay\Desktop\Servers.txt

foreach ($line in $CSVData){

    Invoke-Command -VMName $line.newname -Credential administrator -ScriptBlock {
        Param($incomingname)
    
        Rename-Computer -NewName $incomingname -Restart -whatif
    
        } -ArgumentList $line.newname
}

The last thing you need to do AFTER confirming it's going to do what you desire is to remove the -WhatIf parameter from Rename-Computer. Rename-Computer has a -ComputerName parameter as well, fyi.

Either of these could also be written like this since there is only one property on $CSVData that we care about

$CSVData = import-csv -Path C:\Users\Itay\Desktop\Servers.txt

foreach ($name in $CSVData.newname){

    Invoke-Command -VMName $name-Credential administrator -ScriptBlock {Rename-Computer -NewName $using:name -Restart -whatif}
}

or

$CSVData = import-csv -Path C:\Users\Itay\Desktop\Servers.txt

foreach ($name in $CSVData.newname){

    Invoke-Command -VMName $name -Credential administrator -ScriptBlock {
        Param($incomingname)
    
        Rename-Computer -NewName $incomingname -Restart -whatif
    
        } -ArgumentList $name
}
Doug Maurer
  • 8,090
  • 3
  • 12
  • 13
  • IT WORKS ! thank you very much ! but can you please explain me what does it mean --> $line.newname and how $incomingname recevied the name i want to rename the computer how does $incomingname know to receive new name –  Aug 18 '20 at 10:43
  • 1
    When you import CSV, you end up with an object that has one or more properties. You need to reference them with the dot property syntax - $computers.newname in your original code. The $incomingname I named it that way to hopefully clarify that it's a parameter that you need to pass in the name to with -argumentlist. Whatever is passed to the argument list will be available as `$incomingname` check these links for more info on objects https://adamtheautomator.com/powershell-objects/ https://mcpmag.com/articles/2017/06/01/working-with-object-types-in-powershell.aspx – Doug Maurer Aug 18 '20 at 13:02