1

FIRST POST IN STACKOVERFLOW! I never asked any questions until now. Please, don't hit me too hard lol.

I am trying to create a powershell script to grab a name entered in a config file and feed it into the script. (Renaming a computer)

It's worked before, I swear it... just as is. But I have recently moved all my files to another test system and now it's showing this... like it cannot read or see anything.

I tried testing it out, seeing if it was reading/gathering from the right place so I put a write-host in to see what it was, it did read correctly.

I put the -TotalCount in to grab the SECOND line, that is correct - right?

Why is this failing. And what is more stupid is that IT WAS JUST WORKING.

CODE:

$password =XXXXXXXX | ConvertTo-SecureString -asPlainText -Force 
$username = XXXXXXXX 
$credential = New-Object System.Management.Automation.PSCredential($username,$password) 
$compname = (Get-Content -path .\0CONFIGURATION.txt -TotalCount 2) 

Rename-Computer -NewName $compname -LocalCredential $credential -PassThru 

Write-Host $compname

ERROR:

Rename-Computer : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 
'NewName'. Specified method is not supported.
At line:6 char:26
+ Rename-Computer -NewName $compname -LocalCredential $credential -Pass ...
+                          ~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Rename-Computer], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.RenameComputerCommand 

Screen shot of my failures

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • It's the computer I am running the script on that I am changing the name of - locally whenever this folder is moved to a new system I want to run this script, grab the computer name from the config file and apply it - restart – LetsMakeItWork Feb 04 '20 at 18:13
  • Can you please copy/paste the actual error (referring to the System.Object[] part) in an [edit] to your question? The error is in the screenshot, but nowhere in the question itself, and it's fairly straight forward. – gravity Feb 04 '20 at 18:18
  • 1
    Also, `TotalCount 2` doesn't 'grab the second line' - it grabs two lines total, hence the System.Object[] error. – gravity Feb 04 '20 at 18:19
  • Do this instead `$compname = (Get-Content -path .\0CONFIGURATION.txt)[1]`. The problem is that u are reading 2 lines from the file and feeding it to the script instead of just the 2nd line as u had desired. – Sid Feb 04 '20 at 18:20
  • There are more than 1 configuration I will be putting in the file, how do I grab a certain line out of a file then? Thanks Gravity for clarifying my misunderstanding – LetsMakeItWork Feb 04 '20 at 18:22
  • Sid - thank you! That worked. I have wracked my brain for hours and I must have made a boo boo. Thank you thank you, just got burnt out today. Phew... praise you!!! – LetsMakeItWork Feb 04 '20 at 18:25
  • Honestly, if u are going to use a text file as input, u have to make sure it only contains the names of the machines. `Get-Content` outputs an array. So you can navigate through the contents of the text file using `Foreach ($item in $compname){#rename code with $item as the computername in each iteration}` – Sid Feb 04 '20 at 18:26
  • Thanks, you actually fixed the other 12 errors I was getting - no clue how this ever worked on the other system. I might have deleted the one that worked when I moved >_< I was just over wracking my brain today on this. I need to read more powershell books. – LetsMakeItWork Feb 04 '20 at 18:29

2 Answers2

0

ANSWER THANKS TO SID (Code below works) THANK YOU!!!!!!! Can tell how wet I am behind the ears.

$password =XXXXXXXX | ConvertTo-SecureString -asPlainText -Force 
$username = XXXXXXXX 
$credential = New-Object System.Management.Automation.PSCredential($username,$password) 
$compname = (Get-Content -path .\0CONFIGURATION.txt)[1]

Rename-Computer -NewName $compname -LocalCredential $credential -PassThru 

Write-Host $compname
0

I put the -TotalCount 2 in to grab the SECOND line, that is correct - right?

No: -TotalCount (whose aliases are -First and -Head) specifies the number of lines to read from (the start of) the file.

If your file has at least 2 lines,

$compname = (Get-Content -path .\0CONFIGURATION.txt -TotalCount 2)

will therefore store a 2-element-array ([object[]]) in $compname, and given that Rename-Computer (sensibly) only accepts a single computer name via its -NewName parameter, you'll get the error message you saw.


Getting a single line from a file:

For smallish files, the simplest, but somewhat wasteful approach is to let Get-Content read all input lines into an array and then simply index into that array (the approach suggested by Sid):

# Line with (0-based) index *1* is the *2nd line.
# Note: Convenient, but reads the entire file first.
$compname = (Get-Content -path .\0CONFIGURATION.txt)[1]

A more efficient, but still potentially wasteful approach, which is also the fastest variant in this case (short of calling .NET methods directly):

# Collect only the first 2 lines in an array, then
# use [-1] to grab the *last* line from that array, which is by 
# definition the 2nd one.
$compname = (Get-Content -path .\CONFIGURATION.txt -First 2)[-1]

The most memory-efficient, but slowest approach is to pipe to Select-Object and use its (0-based)
-Index parameter:

# Selects (outputs) only the line with index 1, i.e. the 2nd line.
# This is most memory-efficient, because by using the pipeline 
# the lines preceding the line of interest merely *stream* 
# (are processed one by one), without the need to first *collect them in an array*.
$compname = Get-Content -path .\CONFIGURATION.txt | Select-Object -Index 1

Getting multiple lines from a file - by range and/or distinct indices:

Note that -Index optionally supports an array of indices to support returning multiple lines, using the .., the range (numbers/characters) operator in this example:

$lines2and3 = Get-Content -path .\CONFIGURATION.txt | Select-Object -Index (1..2)

PowerShell's index operator, [...], offers the same flexibility:

$lines2and3 = (Get-Content -path .\CONFIGURATION.txt)[1..2]

You can even combine multiple ranges and distinct indices, using expressions to specify the indices:

# Get line 2, as well as lines 4 - 6.
# Note the need for unary `,` if the expression starts with a *single* index.
# You wouldn't need that if the expression starts with an array; e.g.:
#    `3..5 + 1` or `3, 4, 5 + 1`
Get-Content -path .\CONFIGURATION.txt | Select-Object -Index (, 1 + 3..5)

# Ditto.
(Get-Content -path .\CONFIGURATION.txt)[, 1 + 3..5]
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • This cleared up some confusion, thanks. It clicked reading this because it was curtailed to my question - really nice! Great teacher haha. – LetsMakeItWork Feb 11 '20 at 14:28