drivera01
Enthusiast
Enthusiast

using an input file

Jump to solution

For most of the scripts I have created I have done:

$vmlist="blah","blah1","blah2"      <--- would like file located for example in c:\tmp\inputfile


foreach ($vm in $vmlist)
   {
     Get-VM $vm | Select-Object   -Property Name,NumCpu |FT -AutoSize

I really would like to use an input file instead of listing it like I am above. I have tinkered with it but  im just not getting it.

Thank you!!!

1 Solution

Accepted Solutions
mattboren
Expert
Expert

Hello, drivera01-

You can use something like Get-Content or Import-Csv to take input from a file.  Since you are just doing a list of names, you could make an input file that has one VM name per line, use Get-Content, and then iterate through the list of VM names, like:

## get the list of VM names from a text file
$vmList = Get-Content C:\temp\inputFile.txt
foreach ($vmName in $vmList) {Get-VM $vmName | Select-Object -Property Name,NumCpu | FT -AutoSize}

Or, in this instance, since Get-VM accepts an array of one or more VM names, you could just pass the hold "imported" list of VM names once you've done the Get-Content call, like:

...
## no need to use a foreach loop in this instance
Get-VM $vmList | ft -AutoSize Name,NumCPU

(also cleaned up the select/ft portion a bit).  Other ways to use an input file would involve Import-Csv if you have a bit more involved data, or Import-Clixml if your input data is in XML format.

How does that do?

View solution in original post

19 Replies
mattboren
Expert
Expert

Hello, drivera01-

You can use something like Get-Content or Import-Csv to take input from a file.  Since you are just doing a list of names, you could make an input file that has one VM name per line, use Get-Content, and then iterate through the list of VM names, like:

## get the list of VM names from a text file
$vmList = Get-Content C:\temp\inputFile.txt
foreach ($vmName in $vmList) {Get-VM $vmName | Select-Object -Property Name,NumCpu | FT -AutoSize}

Or, in this instance, since Get-VM accepts an array of one or more VM names, you could just pass the hold "imported" list of VM names once you've done the Get-Content call, like:

...
## no need to use a foreach loop in this instance
Get-VM $vmList | ft -AutoSize Name,NumCPU

(also cleaned up the select/ft portion a bit).  Other ways to use an input file would involve Import-Csv if you have a bit more involved data, or Import-Clixml if your input data is in XML format.

How does that do?

View solution in original post

drivera01
Enthusiast
Enthusiast

Thank you for the repsonse!!!

0 Kudos
markdjones82
Expert
Expert

Driver,

  You can also use a CSV spreadsheet with headers and colums if you need more data.

IE

hosts.csv

hostname,ip

blah.blah.com,10.10.10.10

Then you can do

$data = import-csv hosts.csv

you can reference the members like so:

foreach ($var in $data)

{  get-vmhost $var.hostname

}

You basically can reference the column headers in your loop

http://www.twitter.com/markdjones82 | http://nutzandbolts.wordpress.com
drivera01
Enthusiast
Enthusiast

When I use this method:

## get the list of VM names from a text file
$vmList = Get-Content C:\temp\inputFile.txt

How does the actual VM names need to be placed within the TXT file?

EG:

vm1,vm2

vm1
vm2



I'm just asking cause i'm busy with other things so I don't have time to test this right now..

again thanks!!!
0 Kudos
markdjones82
Expert
Expert

They need to be on a new line each if using just a .txt

vm1

vm2

vm3

if using a CSV format is

Header Header

value    value

http://www.twitter.com/markdjones82 | http://nutzandbolts.wordpress.com
0 Kudos
mattboren
Expert
Expert

Hello, drivera01-

The input file in this case would consist of VM names, one per line (I put that in my original response, but you might have missed it:  "you could make an input file that has one VM name per line").

Anyway, yes, the inputFile.txt contents would be like the latter example that you provided:

inputFile.txt:

vmName0

myVM2

anotherVMName.domain.com

prodVM2

etc..

Give that a shot.

Message was edited by mattboren:  ah, yes, as markdjones82 just responded

drivera01
Enthusiast
Enthusiast

Thanks,

Sorry I missed that.... When I get some free time I for sure will give it a whirl!!

I'm just learning powercli, for that matter powershell I never administered windows servers. But I have found powercli to be very beneficial in managing a VMware environment... Just that darn learning curve....

0 Kudos
drivera01
Enthusiast
Enthusiast

Mark Jones wrote:

Driver,

  You can also use a CSV spreadsheet with headers and colums if you need more data.

IE

hosts.csv

hostname,ip

blah.blah.com,10.10.10.10

Then you can do

$data = import-csv hosts.csv

you can reference the members like so:

foreach ($var in $data)

{  get-vmhost $data.hostname or get-vmhost $data.ip

}

You basically can reference the column headers in your loop

I figured I would play for a few minutes... When I create the csv like this:

hosts.csv

inside there is......

host,ip

host1,1.2.3.4

host2,2.3.4.5

it errors stating "argument is null"

If there is only

host,ip

host1,1.2.3.4

it works fine. I assumed I could add multiple hosts but it does not appear to work..

0 Kudos
markdjones82
Expert
Expert

drivera1,

  You should be able to have infinite amount of rows.  Maybe there is somethign wrong with the format of your file? Do you have a spreadsheet application like excel?

I usually create mine in excel and save as a csv.  The format on your file looks valid though.

Can you post your code?

http://www.twitter.com/markdjones82 | http://nutzandbolts.wordpress.com
0 Kudos
drivera01
Enthusiast
Enthusiast

Weird cause im doing just as you mention.

It works if I populate one set (host and ip)

But once I put two or more….NOPE

Oh well. …. Thanks for the info..

0 Kudos
markdjones82
Expert
Expert

Can you post your code you are testing with? I'm interested in seeing what the issue is.

I did notice above in my foreach loop i had a typo and it should ahve been

foreach ($var in $data){

get-vmhost $var.hostname}

http://www.twitter.com/markdjones82 | http://nutzandbolts.wordpress.com
0 Kudos
esxi1979
Expert
Expert

I have a small Q..My code is

$csv = Import-Csv C:\temp\vm.csv

vm.csv has coloum host

PowerCLI C:\temp> foreach ($line in $csv) {

>> get-vm $($line.host) |FT -Autosize

>> }

>>

Basically I am checking if the host exits in vcenter. Many of them are not & i get he message "... not found..."

I would like to get rid of them & export the o/p to a single file & that file should have the entries of only host which really exits.

Can anyone pls guide.

Thanks

0 Kudos
mattboren
Expert
Expert

Hello, esxi1979-

I believe that you are using "host" to mean VM here, not VMHost (ESXi host).  If so, you could import that CSV and return just the items ("rows") of VMs that exist in the given vCenter like:

Import-Csv C:\temp\vm.csv | Where-Object {Get-VM $_.Host -ErrorAction SilentlyContinue}

Specifying the ErrorAction parameter a value of SilentlyContinue will have the command do just that:  continue and not write the errors to the error stream.

Then, you could do what you will with the output -- pipe it to Export-Csv, pipe it to your next set of commands, etc.  That help?

esxi1979
Expert
Expert

Thanks for responding mattboren

Yes I was referring to Vm & i use in error Host word. I should have been giving more info if i need precise answer from experts Smiley Happy

Your 1 liner looks smarter way to do it !

I was also looking at (| Out-Null) as one way to do it with my one liner..

===

I was writing below Qution actually in vSphere PowerCLI Forum - VMware Developer Center but was giving me error, as soon as I submit, it says "your post deleted"

===

Hello All,

Need a small help, i am missing a small catch in my script.

I have a bunch of VMs & i need to check if they really exits in our vcenter env. I have the big list in a csv file.

Here is my code

input file :vm.csv

host    ip

xxx    10.xx

xxx    10.xxx

============================================================================================================

$csv = Import-Csv C:\temp\vm.csv

PowerCLI C:\temp> foreach ($line in $csv) { Get-VM $($line.host) |export-csv c:\temp\960-$(line.host).csv}

============================================================================================================

as most of the VMs do not exits & hence the final file is empty & also its empty coz i suspect the code do not have sleep stetement .. not the smart script .. infact the file name does not take the vm name ( ie c:\temp\960-$(line.host).csv)

Can someone pls give a fix..

Pls note there are few vms do exist (i checked manually)

Thanks

0 Kudos
mattboren
Expert
Expert

Hello, esxi1979-

Ok, then.  Looks like you have just a couple of small issues in that one-liner.  It is trying to create a new CSV for each VM, but the name is not unique (the "$(line.host)" part is $null, so it is overwriting a CSV named "960-.csv" each time w/ the current VM's info).

To get a CSV of the lines of the input CSV that correspond to VMs that actually exist in the current vCenter, it would be something like:

Import-Csv C:\temp\vm.csv | Where-Object {Get-VM $_.Host -ErrorAction SilentlyContinue} | Export-Csv -NoTypeInformation c:\temp\VMsThatExist.csv -UseCulture

Or, if you want some info for the VMs from vCenter whose names exist in the source CSV file, something like:

Get-VM -Name (Import-Csv C:\temp\vm.csv | %{$_.Host}) -ErrorAction SilentlyContinue | 
   
Select Name,PowerState,NumCpu,MemoryGB | Export-Csv -NoTypeInformation c:\temp\VMsThatExist_info.csv -UseCulture

How do those do for you?

esxi1979
Expert
Expert

Hi mattboren

Works gr8... you did that like a pro... exporting it to a single xls makes more sense  so i am going with the later solution ..

Thanks a lot ..

0 Kudos
Arulssj2
Contributor
Contributor

$vms = Get-Content C:\Users\cad6567\Desktop\vms.txt

foreach ($vm in $vms) {Get-BrokerMachine -HostedMachineName $vm | Select-Object HostedMachineName, @{n='AssocaitedUserName';e={$_.AssociatedUserNames}}, PowerState}

I know this isnt exactly related to VMware. But I need some help in getting this output in a csv format or text format.

Im able to get the required output but just not in a file.

Can someone please help?

0 Kudos
LucD
Leadership
Leadership

Try like this.

A ForEach loop doesn't place anything on the pipeline, so we have to capture the output in a variable, and then pipe that to the CSV file

$vms = Get-Content C:\Users\cad6567\Desktop\vms.txt

$report = foreach ($vm in $vms) {

    Get-BrokerMachine -HostedMachineName $vm |

    Select-Object HostedMachineName,

        @{n='AssocaitedUserName';e={$_.AssociatedUserNames}},

        PowerState

}

$report | Export-Csv report.csv -NoTypeInformation -UseCulture


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

Arulssj2
Contributor
Contributor

Thank you very much for that, LucD. It worked!

0 Kudos