Changing windows hostname automatically after nslookup.

This topic contains 6 replies, has 3 voices, and was last updated by Profile photo of Steve Luther Steve Luther 1 year, 9 months ago.

  • Author
    Posts
  • #23061
    Profile photo of Steve Luther
    Steve Luther
    Participant

    Hi Experts.

    I have an issue that I can not seem to resolve and I am a complete Powershell newbie.

    I am using HPSA to do unattended installations of Windows 2008/2008R2/20012/2012R2

    The installations work fine and get a dhcp address, I then use a powershell script to do an nslookup of the supplied dhcp address to get the hostname then set that as the hostname inplace fo the default one I supply in my unattend.xml file.

    The script works fine on 2008R2, 2012 and 2012 R2 in the following languages:

    English
    German
    Spanish
    Portuguese

    It runs and changes the hostname as expected which then gets set after a reboot.

    However it does not work in:

    French
    Russian
    Korean
    Japanese
    Chinese.

    In theses languages I get an error that there is a missing terminator ".
    However as it works in other languages I am confused as to what or where this error is coming from.

    Here is my script:

    powershell -command "$name=((gwmi Win32_NetworkAdapterConfiguration | ? {$_.IPAddress -ne $null }).ipaddress | Select-Object -First 1 | nslookup $_ | Select-String -Pattern \"Name:\").Line; $name = $name -Replace \"Name:\", \"\"; $name=$name.Trim(); $nameSplit = $name -split \"\.\"; $name = $nameSplit[0]; netdom renamecomputer $env:COMPUTERNAME /newname:$name /force"

    I change the word Name in two places for the languages that work.

    But for the languages it does not work on I get the following error:

    powershell : The string is missing the terminator: ".
    At line:1 char:1
    + powershell -command "$name=((gwmi Win32_NetworkAdapterConfiguration | ? {$_.IPAd ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (The string is missing the terminator: ".:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

    + CategoryInfo : ParserError: ( [], ParentContainsErrorRecordEx
    ception
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

    So can someon please tell me what is wrong, where I should put this missing dot or even rewrite the script better?

    Thanks
    Steve

  • #23063
    Profile photo of Daniel Krebs
    Daniel Krebs
    Participant

    Hi Steve,

    I would rewrite it and use a script file (.ps1) instead.

    PowerShell.exe -File RenameComputerFromDHCP.ps1

    I assume you have at least PowerShell 3.0 installed in your build. So instead of doing prayer based parsing of the NSLookup output I would use the .NET Framework functionality to resolve the IP to the hostname. The parsing of the NSLookup output most likely fails because the output is in the local language.

    $IPv4Addresses = @(
        Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "DHCPEnabled=True AND IPEnabled=True" |
            Select-Object -ExpandProperty IPAddress | Where-Object { ([IPAddress]$_).AddressFamily -eq 'InterNetwork' }
    )
    
    if ($IPv4Addresses.Count -gt 0) {
    
        $HostEntry = [System.Net.Dns]::GetHostEntry($IPv4Addresses[0])
        if ($HostEntry) {
    
            $NewName = $HostEntry.HostName.Split('.')[0].ToUpper()
            Rename-Computer -NewName $NewName -Force -Restart
        }
    }
    

    I hope above helps.

    Best,
    Daniel

  • #23070
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    If you can't put this into a ps1 file for some reason, you'll probably have a much better experience by using the -EncodedCommand parameter of powershell.exe instead of -Command. That gets around all of the silly escaping / quoting rules that you'd need to try to get right. -EncodedCommand takes a base64-encoded string of the UTF-16 representation of the PowerShell code that needs to be executed.

    I also agree with Daniel's use of the [System.Net.Dns] class instead of trying to parse the console output from nslookup; multiple language / culture tends to be what makes pre-PowerShell scripting such a fragile affair. However, just for demonstration purposes, here's how you'd convert your original code to use -EncodedCommand. The only thing I've done is broken the code up into multiple lines (and removed semicolons) for readability, and removed the now-unnecessary backslashes that were escaping some of your double quotation marks:

    $command = @'
        $name=((gwmi Win32_NetworkAdapterConfiguration |
        ? {$_.IPAddress -ne $null }).ipaddress |
        Select-Object -First 1 |
        nslookup $_ |
        Select-String -Pattern "Name:").Line
        
        $name = $name -Replace "Name:", ""
        $name = $name.Trim()
        $nameSplit = $name -split "\."
        $name = $nameSplit[0]
        
        netdom renamecomputer $env:COMPUTERNAME /newname:$name /force
    '@
    
    $bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
    $base64 = [System.Convert]::ToBase64String($bytes)
    $base64 | clip.exe
    

    This puts the encoded command onto your clipboard, where you could then paste it into your call to PowerShell.exe. That would look like this:

    powershell.exe -EncodedCommand IAAgACAAIAAkAG4AYQBtAGUAPQAoACgAZwB3AG0AaQAgAFcAaQBuADMAMgBfAE4AZQB0AHcAbwByAGsAQQBkAGEAcAB0AGUAcgBDAG8AbgBmAGkAZwB1AHIAYQB0AGkAbwBuACAAfAANAAoAIAAgACAAIAA/ACAAewAkAF8ALgBJAFAAQQBkAGQAcgBlAHMAcwAgAC0AbgBlACAAJABuAHUAbABsACAAfQApAC4AaQBwAGEAZABkAHIAZQBzAHMAIAB8AA0ACgAgACAAIAAgAFMAZQBsAGUAYwB0AC0ATwBiAGoAZQBjAHQAIAAtAEYAaQByAHMAdAAgADEAIAB8AA0ACgAgACAAIAAgAG4AcwBsAG8AbwBrAHUAcAAgACQAXwAgAHwADQAKACAAIAAgACAAUwBlAGwAZQBjAHQALQBTAHQAcgBpAG4AZwAgAC0AUABhAHQAdABlAHIAbgAgACIATgBhAG0AZQA6ACIAKQAuAEwAaQBuAGUADQAKACAAIAAgACAADQAKACAAIAAgACAAJABuAGEAbQBlACAAPQAgACQAbgBhAG0AZQAgAC0AUgBlAHAAbABhAGMAZQAgACIATgBhAG0AZQA6ACIALAAgACIAIgANAAoAIAAgACAAIAAkAG4AYQBtAGUAIAA9ACAAJABuAGEAbQBlAC4AVAByAGkAbQAoACkADQAKACAAIAAgACAAJABuAGEAbQBlAFMAcABsAGkAdAAgAD0AIAAkAG4AYQBtAGUAIAAtAHMAcABsAGkAdAAgACIAXAAuACIADQAKACAAIAAgACAAJABuAGEAbQBlACAAPQAgACQAbgBhAG0AZQBTAHAAbABpAHQAWwAwAF0ADQAKACAAIAAgACAADQAKACAAIAAgACAAbgBlAHQAZABvAG0AIAByAGUAbgBhAG0AZQBjAG8AbQBwAHUAdABlAHIAIAAkAGUAbgB2ADoAQwBPAE0AUABVAFQARQBSAE4AQQBNAEUAIAAvAG4AZQB3AG4AYQBtAGUAOgAkAG4AYQBtAGUAIAAvAGYAbwByAGMAZQA=
    
  • #23071
    Profile photo of Steve Luther
    Steve Luther
    Participant

    Hi.

    I have tried Daniels way and it fails with the following error.

    Rename-Computer : Skip computer 'ChangeMe' with new name 'CHANGEME' because
    the new name is the same as the current name.
    At C:\windows\temp\rename.ps1:12 char:9
    + Rename-Computer -NewName $NewName -Force -Restart
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (CHANGEME:String) [Rename-Compu
    ter], InvalidOperationException
    + FullyQualifiedErrorId : NewNameIsOldName,Microsoft.PowerShell.Commands.R
    enameComputerCommand

    It seems to be trying to apply the same name it already has rathe rthan doing an nslookup of its dhcp address.

    Dave I don't get what you mean about pasting the clipboard output.

    This is a totally unattended install using HP Server Automation where a user requests a system in whatever language and it installs it with no administrator interaction.

    I have put Daniels script into a ps1 file copied it over with the installation and then executed it automatically.

    Can I put your code up to thr @ sign in a ps1 file and execute it or do I need the last 3 lines aswell?

    Sorry for being dim but this is all new to me.

    Cheers
    Steve

  • #23072
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    The code with the @ sign is showing you how to generate the value that you would pass to the -EncodedCommand parameter of powershell.exe. You would paste that encoded command (not the code with the @ itself, but the base64 string it produces) into your unattend.xml file.

    In the second Code block, I showed what this would look like in your unattend.xml file. You could even just copy and paste that as-is, if you like; it's the actual encoded version of this code:

        $name=((gwmi Win32_NetworkAdapterConfiguration |
        ? {$_.IPAddress -ne $null }).ipaddress |
        Select-Object -First 1 |
        nslookup $_ |
        Select-String -Pattern "Name:").Line
     
        $name = $name -Replace "Name:", ""
        $name = $name.Trim()
        $nameSplit = $name -split "\."
        $name = $nameSplit[0]
     
        netdom renamecomputer $env:COMPUTERNAME /newname:$name /force
    

    However, I don't know if this code will work as-is on your various languages. Could be that there's still going to be a bug in there somewhere.

  • #23073
    Profile photo of Steve Luther
    Steve Luther
    Participant

    No this code only works on English, German, Spanish and Portuguese.

  • #23226
    Profile photo of Steve Luther
    Steve Luther
    Participant

    Hi Guys,

    so are we stuck on this then?

You must be logged in to reply to this topic.