user6888062
user6888062

Reputation: 373

Variable is array instead of string?

I wrote this small script and when I test Write-Host $serial it appears fine, but when it is running in the background $serial seems to contain an array.

It tries to rename computer to C000@{SerialNumber=F7ZL3F2} instead of just C000F7ZL3F2.

What should I do to just get string not this array?

Import-Module ActiveDirectory
Get-ADComputer -Filter {Name -like 'DESKTOP-*'} -Properties * | Select Name, DNSHostName | ForEach-Object {
    $rtn = Test-Connection -CN $_.dnshostname -Count 1 -BufferSize 16 -Quiet
    if ($rtn -match 'True') { 
        $serial = Get-WMIObject Win32_Bios -ComputerName $_.name | Select-String SerialNumber
        $serial = "C000$serial"
        // Write-Host $serial
        Rename-Computer -ComputerName $_.name -NewName $serial -DomainCredential $mycreds -Force -Restart
    }
}

Upvotes: 1

Views: 250

Answers (3)

Vladimir Bundalo
Vladimir Bundalo

Reputation: 655

Why are you using Select-String? I would use Select-Object and then -ExpandProperty

Import-Module ActiveDirectory

Get-ADComputer -Filter {Name -like 'DESKTOP-*'} -Properties * | Select Name, DNSHostName | ForEach-Object {

  $rtn = Test-Connection -CN $_.dnshostname -Count 1 -BufferSize 16 -Quiet

  if ($rtn -match 'True') { 
  $serial = Get-WMIObject Win32_Bios -ComputerName $_.name | Select-Object -ExpandProperty SerialNumber

  $serial = "C000$serial"

  // Write-Host $serial

  Rename-Computer -ComputerName $_.name -NewName $serial -DomainCredential $mycreds -Force -Restart
    }

}

Upvotes: 1

Vivek Kumar Singh
Vivek Kumar Singh

Reputation: 3350

There are two mistakes to be pointed out in your code -

  1. $serial = Get-WMIObject Win32_Bios -ComputerName $_.name | Select-String SerialNumber

    The Select-String cmdlet searches for text and text patterns in input strings and files. Where as the basetype output of Get-WMIObject Win32_Bios is System.Management.ManagementBaseObject

    (Get-WMIObject Win32_Bios).Gettype()
    IsPublic IsSerial Name             BaseType
    -------- -------- ----             --------
    True     True     ManagementObject System.Management.ManagementBaseObject
    

    In such cases, instead of Select-String, you can use Select-Object to choose amongst the properties. Since, Serial Number is one of the properties returned by your input command.

  2. $serial = "C000$serial"

    The output of $serial will be something like this:

    SerialNumber
    
    5CXXXXYYYXZZZ

    Again, you can call it directly by $serial.SerialNumber. So your overall code will be

    Import-Module ActiveDirectory
    
    Get-ADComputer -Filter {Name -like 'DESKTOP-*'} -Properties * | Select Name, DNSHostName | ForEach-Object {
        $rtn = Test-Connection -CN $_.dnshostname -Count 1 -BufferSize 16 -Quiet
    
        if ($rtn -match 'True') { 
            $serial = Get-WMIObject Win32_Bios -ComputerName $_.name |
                      Select-Object SerialNumber
    
            $serial = "C000$($serial.SerialNumber)"
    
            Rename-Computer -ComputerName $_.name -NewName $serial -DomainCredential $mycreds -Force -Restart
        }
    }
    

    Or you can use -ExpandProperty parameter of the Select-Object cmdlet like

    $serial = Get-WMIObject Win32_Bios -ComputerName $_.name |
              Select-Object -ExpandProperty SerialNumber
    $serial = "C000$serial"
    

Upvotes: 3

boxdog
boxdog

Reputation: 8442

Try changing this line:

$serial = Get-WMIObject Win32_Bios -ComputerName $_.name |
            Select-String SerialNumber

to this:

$serial = (Get-WMIObject Win32_Bios -ComputerName $_.name).SerialNumber

or this:

$serial = Get-WMIObject Win32_Bios -ComputerName $_.name |
           Select-Object -ExpandProperty SerialNumber

Upvotes: 1

Related Questions