PowerShell Scripting for System Center VMM - powershell

Am new to scripting kindly help me write a script that will connect to VMM and get details such as below.
Name : ABC Machine
CPUCount : 8
Memory : 8192
DynamicMemoryEnabled : False
VHDType : DynamicallyExpanding
MaximumSize : 214748364800
Size : 4194304
Location : C:\ClusterStorage\Volume3\CRB\CRB Test Machine_disk_1.vhdx
Classification : Silver
VHDType : DynamicallyExpanding
MaximumSize : 4748364800
Size : 41304
Location : C:\ClusterStorage\Volume2\CRB\CRB Test Machine_disk_2.vhdx
Classification : Silver
I have been able to get individual commands to get the info however I am not able to make a script that will do it for all VMs and convert disk sizes to GB
My working commands are
Get-SCVirtualMachine -Name "ABC Machine" | select Name, CPUCount, Memory, DynamicMemoryEnabled | fl
$DiskINfo = Get-SCVirtualDiskDrive -VMMServer "abc.abcgroupcloud.com" -VM "ABC Machine"
$DiskINfo.VirtualHardDisk | select VHDType, MaximumSize, Size, Location, Classification

1- create an array with all the VM names (or read it from a file with get-content)
2- use a foreach loop to excecute you script over all these VM
3- use a calulated property to display the size in Gb
$computers=#("ABC machine","XYZ machine")
$computers | foreach-object {
Get-SCVirtualMachine -Name $_ | select Name, CPUCount, Memory, DynamicMemoryEnabled | fl
$DiskINfo = Get-SCVirtualDiskDrive -VMMServer "abc.abcgroupcloud.com" -VM $_
$DiskINfo.VirtualHardDisk | select VHDType, MaximumSize, #{Name="Size in Gb";Expression={$($_.size)Mb / 1Gb}}, Location, Classification
}

Old question, but just to add some info.
This will get all the Virtual Machines in your host group in VMM, after entering the correct host group name.
$VMs will be the array, which will contain all the details you are after.
$hg = Get-SCVMHostGroup -Name "My Hostgroup Name"
$hosts = Get-SCVMHost -VMHostGroup $hg
$VMs = $null
ForEach ($h in $hosts)
{
$VMs += Get-SCVirtualMachine -VMHost $h
}

Related

Powershell. Why where {} directive can not find two matching DeviceID? One taken from Win32_VideoController, another from Regedit value

Here is code
# | Get DeviceID and Name of GPUs presented in system
$GPU_Inf = Get-CIMInstance -Query "SELECT Caption, PNPDeviceID from Win32_VideoController"
# | Obtain info on GPUs DeviceID and MemorySize from Regedit
$mem_devid_value = get-itempropertyvalue -path "HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4D36E968-E325-11CE-BFC1-08002BE10318}\????" -Name MatchingDeviceId, HardwareInformation.qwMemorySize
# | For Each element in GPU_Inf
foreach ($i in $GPU_Inf) {
Write-Host "Current PNPDeviceID from GPU_Inf is" $i.PNPDeviceID
Write-Host "Array of MatchingDeviceID and Memory Size from Regedit is" $mem_devid_value
Write-Host "Our MatchingDeviceID from Regedit is" $mem_devid_value[6]
}
$current_dev_id = $mem_devid_value | where { $_ -like $GPU_Inf."PNPDeviceID"}
Write-Host "Device ID that match is" $current_dev_id
And the output shows that where {} directive somehow fail to find matching DeviceIDs
Current PNPDeviceID from GPU_Inf is PCI\VEN_10DE&DEV_128B&SUBSYS_128B10DE&REV_A1\4&1A8B4BFC&0&0008
Array of MatchingDeviceID and Memory Size from Regedit is pci\ven_10de&dev_1c03 6442450944 pci\ven_10de&dev_1402 2147483648 pci\ven_10de&dev_0641 536870912 pci\ven_10de&dev_128b 2147483648
Our MatchingDeviceID from Regedit is pci\ven_10de&dev_128b
Device ID that match is
Last line is blank while it must contain mathing DeviceID from where {} directive
May be there is some wrong type of element massive or smth like this?
I managed to figure out how to make it work
# | Get DeviceID and Name of GPUs presenterd in system
$GPU_Inf = Get-CIMInstance -Query "SELECT Caption, PNPDeviceID from Win32_VideoController"
# | Write to collection DeviceID and HardwareInformation.qwMemorySize from all registry branches
$x = get-itemproperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4D36E968-E325-11CE-BFC1-08002BE10318}\????" -Name MatchingDeviceId, HardwareInformation.qwMemorySize | where { $GPU_Inf.PNPDeviceID -like "$($_.MatchingDeviceID)*" }
# | See that it works
$x.MatchingDeviceID
$x.'HardwareInformation.qwMemorySize'

Output OS in Azure DevOps

I'm trying to get the disk config, amongst other information from the guest OS (windows) and I can't seem to work out how to get the information using Azure DevOps, this is required as we would like to Automate the task at the point of migration to see what size disks are added and what spare capacity there is. Also we'll be expanding on this with further WMI queries, but I think once I can run a script against the guest OS I can pull out most of the details I need.
Azure DevOps has Contributor on the subscription
I'm using an inline script:
Invoke-AzVMRunCommand -ResourceGroupName "$(ResourceGroupName)' -Name '$(VMName)' -CommandId 'RunPowerShellScript' -ScriptPath ".\_snapshots\drop\CSV\disk.ps1" -Confirm:$false
The disk.ps1 script is:
$lists = Get-WmiObject Win32_LogicalDisk | ? {$_.VolumeName -ne "Temporary Storage"}
$Report = #()
foreach ($list in $lists) {
$info = "" | Select-Object DeviceID,"Size (GB)","FreeSpace (GB)","% FreeSpace",VolumeName
$info.DeviceID = $list.DeviceID
$info.'Size (GB)' = [math]::Round($list.size / 1GB)
$info.'FreeSpace (GB)' = [math]::Round($list.FreeSpace / 1GB)
$info.'% FreeSpace' = [math]::Round((($info.'FreeSpace (GB)' * 100) / $info.'Size (GB)'),0)
$info.VolumeName = $list.VolumeName
$report+=$info
}
$report
The output I get is:
Value : {Microsoft.Azure.Management.Compute.Models.InstanceViewStatus,
Microsoft.Azure.Management.Compute.Models.InstanceViewStatus}
Name :
StartTime :
EndTime :
Status : Succeeded
Error :
Output :
Capacity : 0
Count : 0
Item :
What should I get is:
Value[0] :
Code : ComponentStatus/StdOut/succeeded
Level : Info
DisplayStatus : Provisioning succeeded
Message : DeviceID : C:
Size (GB) : 127
FreeSpace (GB) : 117
% FreeSpace : 92
VolumeName : Windows
I get this when I run the script through PowerShell, same version in both cases.
Can anyone see what I'm missing or where I'm going wrong?
Thanks in advance :)
Try to change the inline script as below:
$run = Invoke-AzVMRunCommand -ResourceGroupName "$(ResourceGroupName)' -Name '$(VMName)' -CommandId 'RunPowerShellScript' -ScriptPath ".\_snapshots\drop\CSV\disk.ps1" -Confirm:$false
Write-Host $run.Value[0]
If you want to get the specific message, you could also use:
Write-Host $run.Value[0].Message

How to Get Actual Hard Disk Memory of A VM?

Is it possible to get the actual hard disk usage of a virtual machine?
Measure-VM -Name * | select-object -property TotalDiskAllocation
The TotalDiskAllocation property gets the total disk space assigned to the VM and even though this is helpful I also need to know how much is really being used.
For example, if a VM has 150 GB of allocated memory and it only uses 50 GB, is there any Powershell command that will be able to extract the 50 GB? If yes, how will I be able to incorporate that script to the script above?
Based on your attempt to use Measure-VM, I assumed you are using Hyper-V. I use something similar to this in one of my Hyper-V scripts:
(Get-VM dechiro1).HardDrives | ForEach {
$GetVhd = Get-VHD -Path $_.Path
[pscustomobject]#{
Name = $_.Name
Type = $GetVhd.VhdType
ProvisionedGB = ($GetVhd.Size / 1GB)
CommittedGB = ($GetVhd.FileSize / 1GB)
}
}
Basically, for each of the virtual machine's hard drives, use Get-VHD to get the VHD details which includes the full size and what I refer to as the committed size (actual space on disk).
Example output:
Name Type ProvisionedGB CommittedGB
---- ---- ------------- -----------
Hard Drive on IDE controll... Dynamic 20 0.00390625
Hard Drive on IDE controll... Dynamic 40 0.00390625
Edit:
If you wanted to pull from every VM and include the VM name with the returned object and you prefer to use the pipeline form, this will work:
Get-VM | ForEach { $Vm = $_; $_.HardDrives } | ForEach {
$GetVhd = Get-VHD -Path $_.Path
[pscustomobject]#{
Vm = $Vm.Name
Name = $_.Name
Type = $GetVhd.VhdType
ProvisionedGB = ($GetVhd.Size / 1GB)
CommittedGB = ($GetVhd.FileSize / 1GB)
}
}

2 inputs for Set-Annotation

I'm looking to use this command to set annotations on VMware virtual machines.
Set-Annotation -entity $vm -CustomAttribute "Owner" -Value "$owner"
I need the script to read 2 input files during the same loop. One input for the entity name and one for the value.
If we make 2 text files,
file 1 =
vm1
vm2
vm3
file 2 =
john
bob
ken
I need the script to do:
Set-Annotation -entity vm1 -CustomAttribute "Owner" -Value "john"
then
Set-Annotation -entity vm2 -CustomAttribute "Owner" -Value "bob"
I've been able to get different loops to run, but nothing correctly.
Try the following:
# Read VM names and owners into parallel arrays.
$vmNames = Get-Content 'file 1'
$owners = Get-Content 'file 2'
# Loop over the VM names with a pipeline and assign the corresponding owner
# by array index, maintained in variable $i.
$vmNames | % { $i = 0 } `
{ Set-Annotation -entity $_ -CustomAttribute "Owner" -Value $owners[$i++] }
You could streamline this by using Get-Content 'file 1' directly as the start of the pipeline, without the need to collect all lines in array variable $vmNames first.

Using PowerShell to replicate right clicking a folder and selecting properties

I am trying to gather the Size/Size on disk and number of files/folders on a very large folder tree.
I have been using a script like the follow to gather some of this:
Get-ChildItem "C:\test" -recurse | Measure-Object -Sum Length | Select-Object `
#{Name="Path"; Expression={$directory.FullName}},
#{Name="Files"; Expression={$_.Count}},
#{Name="Size"; Expression={$_.Sum}}
Path Files Size
---- ----- ----
C:\test 470 11622961
But when I want to gather information on the number of folders and size on disk I'm having to run a separate script; which recuse through the folder tee again (Which takes a long time).
Is there an easy way of accessing the all this information the same way you can get it when you right click a folder and select properties shown below?
Are there any callable .exe files within system32 that can do this?
According to this answer in the Technet forums you can calculate the size on disk like this:
$afz = [MidpointRounding]::AwayFromZero
[math]::Round($_.Length / $clusterSize + 0.5, $afz) * $clusterSize
$clusterSize can be determined with the fsutil command (e.g. for drive C:):
PS C:\> fsutil fsinfo ntfsinfo C:\
NTFS Volume Serial Number : 0x648ac3ae16817308
Version : 3.1
Number Sectors : 0x00000000027ccfff
Total Clusters : 0x00000000004f99ff
Free Clusters : 0x0000000000158776
Total Reserved : 0x00000000000003e0
Bytes Per Sector : 512
Bytes Per Physical Sector : 512
Bytes Per Cluster : 4096
Bytes Per FileRecord Segment : 1024
Clusters Per FileRecord Segment : 0
...
Note that running fsutil requires admin privileges.
With that you can collect the information you're interested in like this:
$rootDir = "C:\test"
$afz = [MidpointRounding]::AwayFromZero
$clusterSize = fsutil fsinfo ntfsinfo (Get-Item $rootDir).PSDrive.Root `
| Select-String 'Bytes Per Cluster' `
| % { $_.ToString().Split(':')[1].Trim() }
$stat = Get-ChildItem $rootDir -Recurse -Force `
| select Name, Length, #{n="PhysicalSize";e={
[math]::Round($_.Length / $clusterSize + 0.5, $afz) * $clusterSize
}}, #{n="Folder";e={[int]($_.PSIsContainer)}},
#{n="File";e={[int](-not $_.PSIsContainer)}} `
| Measure-Object -Sum Length, PhysicalSize, Folder, File
$folder = New-Object -TypeName PSObject -Property #{
"FullName" = $rootDir;
"Files" = ($stat | ? { $_.Property -eq "File" }).Sum;
"Folders" = ($stat | ? { $_.Property -eq "Folder" }).Sum;
"Size" = ($stat | ? { $_.Property -eq "Length" }).Sum;
"SizeOnDisk" = ($stat | ? { $_.Property -eq "PhysicalSize" }).Sum - $clusterSize;
}
You're going to have to accumulate your data in a custom object as you see each item:
$path = "C:\Users\aaron\Projects\Carbon"
$properties = New-Object PsObject -Property #{ 'Path' = $path; 'Files' = 0; 'Folders' = 0; 'Size' = 0 }
Get-ChildItem -Path $path -Recurse |
ForEach-Object {
if( $_.PsIsContainer )
{
$properties.Folders++
}
else
{
$properties.Size += $_.Length
$properties.Files++
}
}
$properties