$machines is getting a single string. You’re asking for a “location and file name of your input.” The foreach loop will only have that one string to enumerate through, and it won’t be a computer name. Was your intent to read computer names from a file?
$inputfile = Read-Host "Enter input filename, must be one computer name per line"
$computers = Get-Content $inputfile
foreach ($computer in $computers) {
}
Second, yes, you do actually have to use the computer name with Get-WmiObject. The command defaults to querying the local computer.
That’s how you’d USE the $computer variable from the foreach loop.
Additionally, you’re not going to like the output when you send each computer through Export-CSV like that. You’re going to end up overwriting the file, so it’ll only contain the last computer processed. A typical approach would be to handle the processing and the output as separate steps.
function Get-Stuff {
$inputfile = Read-Host "Enter input filename, must be one computer name per line"
$computers = Get-Content $inputfile
foreach ($computer in $computers) {
Get-WmiObject -Class Win32_Whatever -ComputerName $computer
}
}
Get-Stuff | Export-CSV outputfile.csv
Or even better, make the input a mandatory parameter so the shell will prompt for it:
Also, “Ignore” is not a valid ErrorAction. You probably mean “SilentlyContinue.” Run “help about_common_param*” in the shell for more details. [EDIT: Was reminded Ignore is valid in v3; I’ve still got my head in v2 this morning]
And to perhaps offer a more academic look at the ForEach loop itself: You need to start with a variable that contains one or more objects, such as strings.
$machines = @('SERVER1','SERVER2','SERVER3')
For example. Read-Host can actually only prompt for a single string, so it can’t generate a collection of objects like that. Get-Content produces a collection, with each line in the file being a single object.
ForEach ($machine in $machines) {
}
Takes everything in $machines (remember, it contains 1+ objects) and executes the loop one time “for each” of those objects. Each time through the loop, one object gets plucked out of $machines and stuffed into $machine. That way, inside the loop, you USE $machines to refer to just one thing at a time.
ForEach ($machine in $machines) {
Get-WmiObject Win32_BIOS
}
That’d query your local computer one time “for each” object in $machines. Why your local computer? Because that’s what you told it to do. Being inside a ForEach loop doesn’t magically make commands act differently. THEY don’t know that $machines contains computer names. And not all commands can talk to remote computers.
ForEach ($machine in $machines) {
Get-WmiObject Win32_BIOS -Comp $machine
}
Assuming $machines contains computer names and not, say, AD users, that example would query WMI on each of the machines.