Powershell WMI scripting help

Running into an issue with one of my scripts. The script is designed to query ActiveDirectory and pull a List of Servers.

It then needs to query Multiple remote servers using Remoting and query 2 separate WMI classes. and return the output to a single csv.

Common across all WMI objects is PSComputerName object.

Thanks in advance for your assistance with this.


#Get User Credentials
$cred = Get-Credential
$CorpHypSvr = get-adobject -filter * |? {$_.name -like "*Server*"} |sort Name


#Get Processor Information
$VMonHYP1_Processor = (Invoke-Command -ComputerName $CorpHypSvr.Name -ScriptBlock {"" | Select @{n='TotalPhysicalProcessors';e={(,( gwmi Win32_Processor)).count}}, @{n='TotalPhysicalProcessorCores'; e={ (gwmi Win32_Processor | measure -Property NumberOfLogicalProcessors -sum).sum}}, @{n='TotalVirtualCPUs'; e={ (Get-VM | Get-VMProcessor | measure -Property Count -sum).sum }}, @{n='TotalVirtualCPUsInUse'; e={ (Get-VM | Where { $_.State -eq 'Running'} | Get-VMProcessor | measure -Property Count -sum).sum }}, @{n='TotalMSVMProcessors'; e={ (gwmi -ns root\virtualization\v2 MSVM_Processor).count }}, @{n='TotalMSVMProcessorsForVMs'; e={ (gwmi -ns root\virtualization\v2 MSVM_Processor -Filter "Description='Microsoft Virtual Processor'").count }} } -credential $cred)
#Get Logical to Physical Processor Ratio
$VMonHYP1_ProcessorRatio = (Invoke-Command -ComputerName $CorpHypSvr.Name -ScriptBlock {write-host (@(gwmi -ns root\virtualization\V2 MSVM_Processor).count / (@(gwmi Win32_Processor) | measure -property NumberOfLogicalProcessors -sum).Sum) "virtual processor(s) per logical processor" -f yellow } -credential $cred)
#Memory Information
$VMMonHYP1_Memory = (Invoke-Command -ComputerName $CorpHypSvr.Name -ScriptBlock {get-vm | select vmname, state, dynamicmemoryenabled, @{n="Minimum(MB)";e={$_.memoryminimum/1gb}}, @{n="Maximum(MB)";e={$_.memorymaximum/1gb}}, @{n="Startup(MB)";e={$_.memorystartup/1gb}}, @{n="Currently Assigned(MB)";e={$_.memoryassigned/1gb}}} -credential $cred)
$PSComputers = $CorpHypSvr.Name

#$ComputerObjects = $VMonHYP1_Memory.PSComputerName
#$ComputerObjects = $_

$arrayOfItems = @();


    $outputobject = @{
        PSComputerName = $VMonHYP1_Processor.PSComputerName
        TotalPhysicalProcessors = $VMonHYP1_Processor.TotalPhysicalProcessors
        TotalPhysicalProcessorCores = $VMonHYP1_Processor.TotalPhysicalProcessorCores
        TotalVirtualCPUs = $VMonHYP1_Processor.TotalVirtualCPUs
        TotalVirtualCPUsInUse = $VMonHYP1_Processor.TotalVirtualCPUsInUse
        TotalMSVMProcessors = $VMonHYP1_Processor.TotalMSVMProcessors
        TotalMSVMProcessorsForVMs = $VMonHYP1_Processor.TotalMSVMProcessorsForVMs
        Minimum_MB = $VMonHYP1_Memory.memoryminimum/1gb
        MaximumMB = $VMonHYP1_Memory.memorymaximum/1gb
        StartupMB = $VMonHYP1_Memory.memorystartup/1gb
        CurrentlyAssignedMB = $VMonHYP1_Memory.memoryassigned/1gb
        
              
               
        $object = New-Object psobject -Property $outputobject}

    $arrayOfItems += $outputobject;

    $arrayOfItems = @();
    ForEach($server in $CorpHypSvr) {
    
        $record = @{
            PSComputerName = $VMonHYP1_Processor.PSComputerName
            TotalPhysicalProcessors = $VMonHYP1_Processor.TotalPhysicalProcessors
            TotalPhysicalProcessorCores = $VMonHYP1_Processor.TotalPhysicalProcessorCores
            TotalVirtualCPUs = $VMonHYP1_Processor.TotalVirtualCPUs
            TotalVirtualCPUsInUse = $VMonHYP1_Processor.TotalVirtualCPUsInUse
            TotalMSVMProcessors = $VMonHYP1_Processor.TotalMSVMProcessors
            TotalMSVMProcessorsForVMs = $VMonHYP1_Processor.TotalMSVMProcessorsForVMs
            Minimum_MB = $VMonHYP1_Memory.memoryminimum/1gb
            MaximumMB = $VMonHYP1_Memory.memorymaximum/1gb
            StartupMB = $VMonHYP1_Memory.memorystartup/1gb
            CurrentlyAssignedMB = $VMonHYP1_Memory.memoryassigned/1gb
        };

        $arrayOfItems += $record;
}

Open in new window

LVL 13
ITguy565Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ben Personick (Previously QCubed)Lead Network EngineerCommented:
It would be useful to have you post the errors you're currently having and its c ontext.
0
ITguy565Author Commented:
Ben,

Thanks for commenting on my post.

Currently, The script performs as follows:
  • Connects to AD and Pulls the Server List
  • Pulls WMI information for CorpHypSvr, VMonHYP1_Processor and VMMonHYP1_memory

When the information returns it displays in Multiple Hashtables and can be queried by the $record variable.

However, I need the information to reside not in those hashtables but in a single Columned out CSV or Excel Document. My goal is to have everything from $outputobject to display in it's own column of that CSV.
in addition to that, My foreach loop is not functioning the way I would like.

So far I have not figured out the best way to accomplish that.
0
Bell TechLogixSystems EngineerCommented:
does export-csv not work?
0
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Bell TechLogixSystems EngineerCommented:
you may have to build out a custom array with things ordered out the way you want for your csv table...
0
ITguy565Author Commented:
Export-CSV would work, but  I am not sure how to combine the Hashtables into a single output in order to export the document to CSV.

First Example of the way the Foreach loop is processingExample of the Hashtable output
0
Bell TechLogixSystems EngineerCommented:
break them up into the fields you want, here is an example of building a custom array
$reportarray = @();
FOREACH($server in $servers)
{
    $pcobject = new-object PSObject
	$pcobject | Add-Member NoteProperty -Name "Server" -Value $Server.name
    $pcobject | Add-Member NoteProperty -Name "CPU" -Value $Server.cpu1
    $reportarray += $pcobject;
}
$reportarray|export-csv c:\whatever.csv

Open in new window

0
Bell TechLogixSystems EngineerCommented:
what do you need the hastables to look like?
0
Bell TechLogixSystems EngineerCommented:
doh, I see you were already building a customarray
0
ITguy565Author Commented:
Bell, thanks for your comment on the Array, however, I have attempted it and haven't figured out where I have been going wrong with it. I posted this because I thought that I might get someone that could show me the error of my ways. Can you by chance lead me in that direction or assist with the failure in the code?
0
Bell TechLogixSystems EngineerCommented:
I guess I need a better idea of what you want your hash table to look like.
0
ITguy565Author Commented:
each one of these need to be their own Column with the Common Column being PSComputerName

  •     PSComputerName = $VMonHYP1_Processor.PSComputerName
  •            TotalPhysicalProcessors = $VMonHYP1_Processor.TotalPhysicalProcessors
  •            TotalPhysicalProcessorCores = $VMonHYP1_Processor.TotalPhysicalProcessorCores
  •            TotalVirtualCPUs = $VMonHYP1_Processor.TotalVirtualCPUs
  •            TotalVirtualCPUsInUse = $VMonHYP1_Processor.TotalVirtualCPUsInUse
  •            TotalMSVMProcessors = $VMonHYP1_Processor.TotalMSVMProcessors
  •            TotalMSVMProcessorsForVMs = $VMonHYP1_Processor.TotalMSVMProcessorsForVMs
  •            Minimum_MB = $VMonHYP1_Memory.memoryminimum/1gb
  •            MaximumMB = $VMonHYP1_Memory.memorymaximum/1gb
  •            StartupMB = $VMonHYP1_Memory.memorystartup/1gb
  •            CurrentlyAssignedMB = $VMonHYP1_Memory.memoryassigned/1gb
0
Bell TechLogixSystems EngineerCommented:
Your total physical processors and cores, should those be a .count?
0
Bell TechLogixSystems EngineerCommented:
so
TotalPhysicalProcessors = $VMonHYP1_Processor.TotalPhysicalProcessors.count
and so on?
0
ITguy565Author Commented:
That is correct. Thanks
0
Bell TechLogixSystems EngineerCommented:
so after you adjust that, can you give us a screen print of what it now looks like, and what you are still expecting, looks like your memory calculations aren't working?
0
Bell TechLogixSystems EngineerCommented:
it also looks like they aren't breaking apart into separate objects with PSComputer as the primary for each correct?
0
ITguy565Author Commented:
ok, so I have updated my code.. I am still having an issue with the memory objects however with the get-VM command..

Here is my updated Code Snipit:

$cred = Get-Credential
<# $CorpHypSvr = get-adobject -filter * |? {$_.name -like "*SOMESERVER*"} |sort Name
del C:\scripts\computers.txt
$corpHypSvr.Name >> c:\scripts\computers.txt #>
$Computers = Get-Content -Path C:\scripts\Computers.txt

$AllComputers = @()
foreach ($machine in $Computers) 
{
    $objMemory = (Invoke-Command -ComputerName $machine -ScriptBlock {get-vm | select vmname, state, dynamicmemoryenabled, @{n = "Minimum(MB)"; e = {$_.memoryminimum / 1gb}}, @{n = "Maximum(MB)"; e = {$_.memorymaximum / 1gb}}, @{n = "Startup(MB)"; e = {$_.memorystartup / 1gb}}, @{n = "Currently Assigned(MB)"; e = {$_.memoryassigned / 1gb}}} -credential $cred)
    foreach ($itd in $objMemory) 
    {
        $state = $itd.state
        $DynMemState = $itd.dynamicmemoryenabled
        $minMemoryMB = $itd.memoryminimum/1gb
        $maxMemoryMB = $itd.memorymaximum/1gb
        $startMemoryMB = $itd.memorystartup /1gb
    }

    $Object = New-Object PSObject -Property @{
        Name                             = $machine
        "Total Physical Memory GB"       = $TotalPhysicalMemory
        State                            = $state
        "Dynamic Memory State"           = $DynMemState
        "Minimum Memory"                 = $minMemoryMB
        "Maximum Memory"                 = $maxMemoryMB
        "Startup Memory"                 = $startMemoryMB
    } 
    $AllComputers += $Object

}
$AllComputers | Out-GridView   

Open in new window

0
Bell TechLogixSystems EngineerCommented:
prior to doing any calculations on those fields, do they return anything?
0
oBdACommented:
You're renaming the properties of the VM guests three times: once in the calculated properties, once in the foreach loop, once were you create the final object. You're not doing anyone a favor with this, least of all yourself.
Then in the calculated properties, you name the memory columns "...(MB)", but divide by GB. In the ForEach loop, you try to divide them again by 1GB.
That aside, the construction isn't working at all.
And please don't get all AD objects, just to filter out in PS the ones you don't need (which will be most of them). Use Get-ADComputer and a filter.

That said (sorry), combining the information you've tried to gather in $VMonHYP1_Processor with the one from $VMMonHYP1_Memory doesn't make a lot of sense in my opinion.
Once is about the Hyper-V hosts, the other one about the guests; I'd separate the two.
Try it like this:
#Get User Credentials
$cred = Get-Credential
$serverList = Get-ADComputer -Filter "Name -like '*server*'" * | Sort-Object -Property Name | Select-Object -ExpandProperty Name

#Get HyperV Host Information
$HyperVHostInfo = Invoke-Command -ComputerName $serverList -Credential $cred -ScriptBlock {
	$win32ProcessorList = Get-WmiObject -Class Win32_Processor
	$mSVMProcessorList = Get-WmiObject -Class MSVM_Processor -Namespace root\virtualization\v2 -ErrorAction SilentlyContinue
	$logicalCpuCount = ($win32ProcessorList | Measure-Object -Property NumberOfLogicalProcessors -Sum).Sum
	$virtualCpuCount = @($mSVMProcessorList).Count
	$vMList = $null #Get-VM
	'' | Select-Object -Property `
		@{n='ComputerName';					e={$ENV:ComputerName}},
		@{n='TotalPhysicalProcessors';		e={@($win32ProcessorList).Count}},
		@{n='TotalPhysicalProcessorCores';	e={$logicalCpuCount}},
		@{n='TotalVirtualCPUs';				e={($vMList | Get-VMProcessor | Measure-Object -Property Count -Sum).Sum }},
		@{n='TotalVirtualCPUsInUse';		e={($vMList | Where-Object {$_.State -eq 'Running'} | Get-VMProcessor | Measure-Object -Property Count -Sum).Sum}},
		@{n='TotalMSVMProcessors';			e={$virtualCpuCount}},
		@{n='TotalMSVMProcessorsForVMs';	e={@($mSVMProcessorList | Where-Object {$_.Description -eq 'Microsoft Virtual Processor'}).Count}},
		@{n='ProcessorRatio';				e={$virtualCpuCount / $logicalCpuCount}}
} |
	Select-Object -Property * -ExcludeProperty PSComputerName, RunspaceId |
	Sort-Object -Property ComputerName
$HyperVHostInfo | Out-GridView

#Get HyperV Guest Information
$HyperVGuestInfo = Invoke-Command -ComputerName $serverList -Credential $cred -ScriptBlock {
	$TotalPhysicalMemory = [Math]::Round(((Get-WMIObject -Class Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1gb), 2)
	Get-VM | Select-Object -Property `
		@{n='ComputerName';				e={$ENV:ComputerName}},
		@{n='Total Physical Memory GB';	e={$TotalPhysicalMemory}},
		VMName,
		State,
		@{n='Dynamic Memory State';	e={$_.DynamicMemoryEnabled}},
		@{n='Minimum Memory (MB)';		e={$_.MemoryMinimum / 1mb}},
		@{n='Maximum Memory (MB)';		e={$_.MemoryMaximum / 1mb}},
		@{n='Startup Memory (MB)';		e={$_.MemoryStartup / 1mb}},
		@{n='Currently Assigned (MB)';	e={$_.MemoryAssigned / 1mb}}
} |
	Select-Object -Property * -ExcludeProperty PSComputerName, RunspaceId |
	Sort-Object -Property ComputerName, VMName
$HyperVGuestInfo | Out-GridView

Open in new window

2

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ITguy565Author Commented:
The output that I was able to see was exactly what I was looking for THANKS!!!!

Running into a single issue however with the VMName Variable as shown in the screen shot but that I believe would be the only issue remaining. All output looks as I would like it.

Thanks for your help thus far! You are a gods send!
2018-03-07_13-24-27.png
0
oBdACommented:
Sorry, that was a leftover from testing.
In line 11, simply remove the "$null #" part before Get-VM:
$vMList = Get-VM

Open in new window

0
ITguy565Author Commented:
Perfect! Thanks for your assistance with this!!!
1
ITguy565Author Commented:
Awesome Work! you saved me a TON of time!
1
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.