VMware Cloud Community
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Update DNS

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
Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

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

$reportlocation1 = ".\Prod_Info.csv"

$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

View solution in original post

Reply
0 Kudos
23 Replies
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
Grzesiekk
Expert
Expert
Jump to solution

https://www.jorgebernhardt.com/how-to-set-dns-server-addresses-with-set-dnsclientserveraddress/  +  Invoke-VMSCript
--- @blog https://grzegorzkulikowski.info
Reply
0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

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)"

    }

}

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Are you sure the Where-clause is picking the correct adapter?

Get-WmiObject Win32_NetworkAdapterConfiguration | where {$_.DNSServerSearchOrder -eq "192.168.15.5"}

Can you check with only running

Get-WmiObject Win32_NetworkAdapterConfiguration | Select -ExpandProperty DNSServerSearchOrder


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

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

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

That is returning an array, and the -eq will not work

Try with

Get-WmiObject Win32_NetworkAdapterConfiguration | where {$_.DNSServerSearchOrder -contains "192.168.15.5"}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

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

|

|

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

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.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

$code = @'

$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

Reply
0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

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 ?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

LucD,

I tried as attached but I see script executes without any error but DNS is not getting updated.

Please help, if I have missed anything.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I'm afraid I can't open the attached file


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

not sure, why is happening. I am re-attaching

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

$reportlocation1 = ".\Prod_Info.csv"

$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

Reply
0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

LucD,

I dont see any error but still DNS IP is not getting changed.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

$reportlocation1 = ".\Prod_Info.csv"

$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

Reply
0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Hi LucD,

This works excellent on the server where UAC is disabled but on the UAC enabled server still it doesnt work.

I tried this script to check the UAC status, still it is not working Smiley Sad

Reply
0 Kudos