Hi,
I am trying to update the DNS on all the VMs from the list. Now I am stuck, how to update the DNS IP with 192.168.15.100 and 192.168.15.101.
Please help.
Get-VM MyApp1 | Get-NetworkAdapter |
Select-Object @{N="VM";E={$_.Parent.Name}},
@{N="NIC";E={$_.Name}},
@{N="Network";E={$_.NetworkName}},
MacAddress,
@{N='IP';E={
$vNIc = $_
($_.Parent.ExtensionData.Guest.Net | where { $_.MacAddress -eq $vNIc.MacAddress }).IPAddress -join '|'
}},
@{N='DNS';E={($_.Parent.ExtensionData.Guest.Net.DNSConfig).IPAddress -join ', '}}
Current Output
VM | : MyApp1 |
NIC | : Network adapter 1 |
Network | : 12_dvs |
MacAddress : 00:50:56:97:79:da
IP | : 192.168.3.17 |
DNS | : 192.168.1.5, 192.168.1.6 |
The following seems to be working for me.
I made a few changes:
- I'm not using the Get-WmiObject anymore
- the $code needs to be inside the $scriptblock
- some quoting and escaping was adjusted
$WPassword = "password@123"
$pass = ConvertTo-SecureString -AsPlainText $WPassword -Force
$Creds = New-Object System.Management.Automation.PSCredential ("admin", $pass)
$ScriptBlock = @'
$code = @"
Get-DnsClientServerAddress | where{`$_.ServerAddresses -contains '192.168.15.5'} |
Set-DnsClientServerAddress -ServerAddresses '192.168.15.100','192.168.15.101' -Verbose -Confirm:`$false
"@
function Elevate-Process {
param ([string]$exe = $(Throw "Pleave provide the name and path of an executable"),[string]$arguments)
$startinfo = New-Object System.Diagnostics.ProcessStartInfo
$startinfo.FileName = $exe
$startinfo.Arguments = $arguments
$startinfo.verb = "RunAs"
$startinfo.UseShellExecute = $false
$startinfo.CreateNoWindow = $true
$process = [System.Diagnostics.Process]::Start($startinfo)
}
Elevate-Process -Exe powershell.exe -Arguments "-noninteractive -command &{$code}"
'@
Import-Csv -Path $reportlocation1 -UseCulture -PipelineVariable row |
ForEach-Object -Process {
$sInvoke = @{
VM = $_.Name
GuestCredential = $Creds
ScriptTYpe = 'powershell'
ScriptText = $ScriptBlock
ErrorAction = 'Stop'
}
try{
$result = Invoke-VMScript @sInvoke
"$($row.Name) DNS has been changed"
}
catch{
Throw "Failed for $($row.Name)"
}
$result
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
That is something that is done inside the Guest OS and depends on which type of Guest OS you have running on the VM.
There used to be a Set-VMGuestNetwork cmdlet, but that has been removed.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
I tried as below, the script runs without any error but DNS is not getting updated.
If the execute the commands directly, DNS is getting changed but when I use with invoke-vmscript, it is not working.
Please help
$reportlocation1 = ".\Prod_Info.csv"
$code = @'
$Adapters = Get-WmiObject Win32_NetworkAdapterConfiguration | where {$_.DNSServerSearchOrder -eq "192.168.15.5"}
$Adapters | Set-DnsClientServerAddress -ServerAddresses "192.168.15.100","192.168.15.101"
'@
Import-Csv -Path $reportlocation1 -UseCulture -PipelineVariable row |
ForEach-Object -Process {
$sInvoke = @{
VM = $_.Name
GuestCredential = $Creds
ScriptTYpe = 'powershell'
ScriptText = $code
ErrorAction = 'Stop'
}
try{
$result = Invoke-VMScript @sInvoke
}
catch{
Throw "Failed for $($row.Name)"
}
}
Are you sure the Where-clause is picking the correct adapter?
Can you check with only running
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
Get-WmiObject Win32_NetworkAdapterConfiguration | Select -ExpandProperty DNSServerSearchOrder
I am getting the DNS Server`s IP as below
192.168.15.5
192.168.15.6
That is returning an array, and the -eq will not work
Try with
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
After changing, I am now getting error as below. Also attached the complete script for your reference
ScriptOutput
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| At line:2 char:2
| + | Set-DnsClientServerAddress -ServerAddresses "192.168.15.100","192.168.15.101"}
| + ~
| An empty pipe element is not allowed.
| + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordEx
| ception
| + FullyQualifiedErrorId : EmptyPipeElement
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Did you assign the line with the Where-clause to the variable $adapters?
Looks like that variable is empty
PS: I can't read the ZIP file you attached
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
yes, I assigned the $Adapter variable to the line that you mentioned
$Adapters = Get-WmiObject Win32_NetworkAdapterConfiguration | where {$_.DNSServerSearchOrder -contains "192.168.15.5"}
$Adapters | Set-DnsClientServerAddress -ServerAddresses "192.168.15.100","192.168.15.101"
again attaching the script for your reference
the above command works, if the execute directly on the any server but using the script, it is not working.
I see what happened, you change the delimiters of the here-string to double quotes, which means variable substitution will take place.
Define the $code with single quotes as follows
$Adapters = Get-WmiObject Win32_NetworkAdapterConfiguration | where {$_.DNSServerSearchOrder -contains "192.168.15.5"}
$Adapters | Set-DnsClientServerAddress -ServerAddresses "192.168.15.100","192.168.15.101"
'@
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
I see Invoke-VMScript needs UAC to be disabled on the Servers. After I disabled the UAC on the Servers and rebooting. I am able to make the change using the script
Is there a way to change without disabling the UAC on the Servers ?
Invoke-VMScript does not need UAC to be disabled.
Commands you run in the Guest OS via Invoke-VMScript might require UAC to be disabled to avoid prompting.
And no, if one could bypass UAC that easily, it wouldn't be much of a security measure.
You could try the option with RunAs, but I'm not sure that this will work in this case.
See for example How-to: Run with elevated permissions
You would need to start an elevated PowerShell session from within the non-elevated script you launch via Invoke-VMScript.
For an example with Invoke-VMScript see Invoke-VMScript install App as an administrator
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I'm afraid I can't open the attached file
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
That worked.
Give it a try like this.
I made some changes:
- the $code here-string should be between single quotes
- I avoided the $adapters variable by placing everything in a pipeline construct
- the command value is placed in quotes
- the display of $result shall be inside the ForEach loop
$WPassword = "password@123"
$pass = ConvertTo-SecureString -AsPlainText $WPassword -Force
$Creds = New-Object System.Management.Automation.PSCredential ("admin", $pass)
$code = @'
Get-WmiObject Win32_NetworkAdapterConfiguration |
where {$_.DNSServerSearchOrder -contains "192.168.15.5"} |
Set-DnsClientServerAddress -ServerAddresses "192.168.15.100","192.168.15.101" -Confirm:$false
'@
$ScriptBlock = @"
function Elevate-Process {
param ([string]`$exe = `$(Throw "Pleave provide the name and path of an executable"),[string]`$arguments)
`$startinfo = new-object System.Diagnostics.ProcessStartInfo
`$startinfo.FileName = `$exe
`$startinfo.Arguments = `$arguments
`$startinfo.verb = `"RunAs`"
`$startinfo.UseShellExecute = `"False`"
`$startinfo.CreateNoWindow = `"True`"
`$process = [System.Diagnostics.Process]::Start(`$startinfo)
}
Elevate-Process -Exe powershell.exe -Arguments `"-noninteractive -command '$code'"
"@
Import-Csv -Path $reportlocation1 -UseCulture -PipelineVariable row |
ForEach-Object -Process {
$sInvoke = @{
VM = $_.Name
GuestCredential = $Creds
ScriptTYpe = 'powershell'
ScriptText = $ScriptBlock
ErrorAction = 'Stop'
}
try{
$result = Invoke-VMScript @sInvoke
"$($row.Name) DNS has been changed"
}
catch{
Throw "Failed for $($row.Name)"
}
$result
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
I dont see any error but still DNS IP is not getting changed.
The following seems to be working for me.
I made a few changes:
- I'm not using the Get-WmiObject anymore
- the $code needs to be inside the $scriptblock
- some quoting and escaping was adjusted
$WPassword = "password@123"
$pass = ConvertTo-SecureString -AsPlainText $WPassword -Force
$Creds = New-Object System.Management.Automation.PSCredential ("admin", $pass)
$ScriptBlock = @'
$code = @"
Get-DnsClientServerAddress | where{`$_.ServerAddresses -contains '192.168.15.5'} |
Set-DnsClientServerAddress -ServerAddresses '192.168.15.100','192.168.15.101' -Verbose -Confirm:`$false
"@
function Elevate-Process {
param ([string]$exe = $(Throw "Pleave provide the name and path of an executable"),[string]$arguments)
$startinfo = New-Object System.Diagnostics.ProcessStartInfo
$startinfo.FileName = $exe
$startinfo.Arguments = $arguments
$startinfo.verb = "RunAs"
$startinfo.UseShellExecute = $false
$startinfo.CreateNoWindow = $true
$process = [System.Diagnostics.Process]::Start($startinfo)
}
Elevate-Process -Exe powershell.exe -Arguments "-noninteractive -command &{$code}"
'@
Import-Csv -Path $reportlocation1 -UseCulture -PipelineVariable row |
ForEach-Object -Process {
$sInvoke = @{
VM = $_.Name
GuestCredential = $Creds
ScriptTYpe = 'powershell'
ScriptText = $ScriptBlock
ErrorAction = 'Stop'
}
try{
$result = Invoke-VMScript @sInvoke
"$($row.Name) DNS has been changed"
}
catch{
Throw "Failed for $($row.Name)"
}
$result
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference