Posted in
Windows Powershell,
Windows Server |
No Comment | 3,705 views | 10/07/2014 15:43
You may need to see passthrough disk information from Hyper-V VMs on several clusters.
So you can use following script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| # Get Clusters
$Clusters = Get-Content Clusters.txt
foreach ($Cluster in $Clusters)
{
# Get Cluster Nodes
$ClusterNodes = Get-Cluster $Cluster | Get-ClusterNode
foreach ($ClusterNode in $ClusterNodes)
{
# Clear PT Values
$PTDisks = $Null;
# Get Passthrough Disks
$PTDisks = Get-VM -ComputerName $ClusterNode | Get-VMHardDiskDrive | Where Path -like Disk*
if ($PTDisks)
{
# Get VM Name
$VMName = $PTDisks[0].VMName
# Informational Output
Write-Host Working on $VMName..
foreach ($PTDisk in $PTDisks)
{
# Get Passthrough Disk Info
$PTInfo = $PTDisk.Path
# Informational Output
Write-Host $PTInfo
}
# Informational Output
Write-Host " "
Write-Host " "
}
}
} |
# Get Clusters
$Clusters = Get-Content Clusters.txt
foreach ($Cluster in $Clusters)
{
# Get Cluster Nodes
$ClusterNodes = Get-Cluster $Cluster | Get-ClusterNode
foreach ($ClusterNode in $ClusterNodes)
{
# Clear PT Values
$PTDisks = $Null;
# Get Passthrough Disks
$PTDisks = Get-VM -ComputerName $ClusterNode | Get-VMHardDiskDrive | Where Path -like Disk*
if ($PTDisks)
{
# Get VM Name
$VMName = $PTDisks[0].VMName
# Informational Output
Write-Host Working on $VMName..
foreach ($PTDisk in $PTDisks)
{
# Get Passthrough Disk Info
$PTInfo = $PTDisk.Path
# Informational Output
Write-Host $PTInfo
}
# Informational Output
Write-Host " "
Write-Host " "
}
}
}
That will give you disk information output. You should add all clusters names into Cluster.txt file.
Posted in
Windows Powershell,
Windows Server |
No Comment | 2,748 views | 04/07/2014 18:00
Lets assume that you have a 3 years old storage and you are using it to place your virtual machines on Hyper-V Cluster. Then you bought a new storage box, you created LUNs on it and assign them as a CSV volumes on your existing Hyper-V Cluster. So next achievement would be migrating your virtual machines from old storage to new one.
That migration could be a headache if you have many VMs and many storage LUNs. So in that case, you can use following script to migrate Virtual Machines per CSV Volume. Just you need to specify which CSV volume you would like to drain. So let’s assume that volume is Volume1. I will specify that volume by following line:
1
2
| # Target Volume
$TargetVolume = "Volume1" |
# Target Volume
$TargetVolume = "Volume1"
Now you need to specify other CSV Luns as well to filter them. Otherwise, you can migrate a VM to old storage again. So we are filtering them by following lines:
1
2
3
4
5
6
7
8
| # Filtered Volumes
$FilteredVolumes = @()
$FilteredVolumes += $TargetVolume
$FilteredVolumes += "Volume2"
$FilteredVolumes += "Volume3"
$FilteredVolumes += "Volume4"
$FilteredVolumes += "Volume5"
$FilteredVolumes += "Volume6" |
# Filtered Volumes
$FilteredVolumes = @()
$FilteredVolumes += $TargetVolume
$FilteredVolumes += "Volume2"
$FilteredVolumes += "Volume3"
$FilteredVolumes += "Volume4"
$FilteredVolumes += "Volume5"
$FilteredVolumes += "Volume6"
We are creating an array called FilteredVolumes then adding our old storage luns to this array. You will see that I’m also adding $TargetVolume to same array. Because there is a chance to try to migrate a VM to same volume. So that will prevent that kind of issues.
So how can I get destination volume?
1
2
| # Full Query
$FullQuery = '((Get-ClusterSharedVolume |' + $Query + ' Select -ExpandProperty SharedVolumeInfo | Select @{label="Name";expression={(($_.FriendlyVolumeName).Split("\"))[-1]}},@{label="FreeSpace";expression={($_ | Select -Expand Partition).FreeSpace}} | Sort FreeSpace -Descending)[0]).Name' |
# Full Query
$FullQuery = '((Get-ClusterSharedVolume |' + $Query + ' Select -ExpandProperty SharedVolumeInfo | Select @{label="Name";expression={(($_.FriendlyVolumeName).Split("\"))[-1]}},@{label="FreeSpace";expression={($_ | Select -Expand Partition).FreeSpace}} | Sort FreeSpace -Descending)[0]).Name'
As you can notice from the code below, i’m getting all CSV volumes, filtering old storage volumes, sorting new storage CSVs by their free space and selecting the storage which has biggest available disk space.
So I’ll place VM into that volume:
Move-VMStorage -ComputerName "$ClusterNode" -VMName "$VMName" -DestinationStoragePath "C:\ClusterStorage\$Volume\$VMName" |
Move-VMStorage -ComputerName "$ClusterNode" -VMName "$VMName" -DestinationStoragePath "C:\ClusterStorage\$Volume\$VMName"
If you get the idea, now I can share full script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| # Target Volume
$TargetVolume = "Volume1"
# Filtered Volumes
$FilteredVolumes = @()
$FilteredVolumes += $TargetVolume
$FilteredVolumes += "Volume2"
$FilteredVolumes += "Volume3"
$FilteredVolumes += "Volume4"
$FilteredVolumes += "Volume5"
$FilteredVolumes += "Volume6"
# Clear Query
$Query = $Null;
# Create Query
foreach ($FilteredVolume in $FilteredVolumes)
{
$Query = $Query + ' Where {$_.SharedVolumeInfo.FriendlyVolumeName -notlike "*' + $FilteredVolume + '"} |'
}
# Full Query
$FullQuery = '((Get-ClusterSharedVolume |' + $Query + ' Select -ExpandProperty SharedVolumeInfo | Select @{label="Name";expression={(($_.FriendlyVolumeName).Split("\"))[-1]}},@{label="FreeSpace";expression={($_ | Select -Expand Partition).FreeSpace}} | Sort FreeSpace -Descending)[0]).Name'
# Get Cluster Nodes
$ClusterNodes = Get-Cluster | Get-ClusterNode
foreach ($ClusterNode in $ClusterNodes)
{
# Clear Variables
$VMs = $Null;
# Get All Virtual Machines on Target Volume
$VMs = Get-VM -ComputerName "$ClusterNode" | Where ConfigurationLocation -like "C:\ClusterStorage\$TargetVolume\*"
foreach ($VM in $VMs)
{
# Get VM Information
$VMName = $VM.Name
Write-Host " "
Write-Host "Working on $VMName .."
Write-Host "Hyper-V Host: $ClusterNode"
# Get Volume Information
$Volume = Invoke-Expression $FullQuery
# Move Virtual Machine
Move-VMStorage -ComputerName "$ClusterNode" -VMName "$VMName" -DestinationStoragePath "C:\ClusterStorage\$Volume\$VMName"
Write-Host "Done."
}
} |
# Target Volume
$TargetVolume = "Volume1"
# Filtered Volumes
$FilteredVolumes = @()
$FilteredVolumes += $TargetVolume
$FilteredVolumes += "Volume2"
$FilteredVolumes += "Volume3"
$FilteredVolumes += "Volume4"
$FilteredVolumes += "Volume5"
$FilteredVolumes += "Volume6"
# Clear Query
$Query = $Null;
# Create Query
foreach ($FilteredVolume in $FilteredVolumes)
{
$Query = $Query + ' Where {$_.SharedVolumeInfo.FriendlyVolumeName -notlike "*' + $FilteredVolume + '"} |'
}
# Full Query
$FullQuery = '((Get-ClusterSharedVolume |' + $Query + ' Select -ExpandProperty SharedVolumeInfo | Select @{label="Name";expression={(($_.FriendlyVolumeName).Split("\"))[-1]}},@{label="FreeSpace";expression={($_ | Select -Expand Partition).FreeSpace}} | Sort FreeSpace -Descending)[0]).Name'
# Get Cluster Nodes
$ClusterNodes = Get-Cluster | Get-ClusterNode
foreach ($ClusterNode in $ClusterNodes)
{
# Clear Variables
$VMs = $Null;
# Get All Virtual Machines on Target Volume
$VMs = Get-VM -ComputerName "$ClusterNode" | Where ConfigurationLocation -like "C:\ClusterStorage\$TargetVolume\*"
foreach ($VM in $VMs)
{
# Get VM Information
$VMName = $VM.Name
Write-Host " "
Write-Host "Working on $VMName .."
Write-Host "Hyper-V Host: $ClusterNode"
# Get Volume Information
$Volume = Invoke-Expression $FullQuery
# Move Virtual Machine
Move-VMStorage -ComputerName "$ClusterNode" -VMName "$VMName" -DestinationStoragePath "C:\ClusterStorage\$Volume\$VMName"
Write-Host "Done."
}
}
It’s enough to run this script on one of the Cluster Node, so that will start migrating virtual machines. That will also give an output, so you will be able to see which VM you are migrating. I hope you will find it useful. See you!
Posted in
Windows Powershell,
Windows Server |
No Comment | 3,307 views | 03/07/2014 11:34
You can use following script to get pwdlastset value of a computer:
1
| [datetime]::fromfiletime((Get-ADComputer SLESGTRM04 -Properties pwdlastset).pwdlastset) |
[datetime]::fromfiletime((Get-ADComputer SLESGTRM04 -Properties pwdlastset).pwdlastset)
Also you can use conditional query:
1
2
| $RefDate = (Get-Date).AddDays(-90)
Get-ADComputer -Filter * -Properties pwdlastset | Where {[datetime]::fromfiletime($_.pwdlastset) -lt $RefDate} |
$RefDate = (Get-Date).AddDays(-90)
Get-ADComputer -Filter * -Properties pwdlastset | Where {[datetime]::fromfiletime($_.pwdlastset) -lt $RefDate}
If you want to filter workstations:
1
2
| $RefDate = (Get-Date).AddDays(-90)
Get-ADComputer -Filter * -Properties pwdlastset,OperatingSystem | Where OperatingSystem -like "*Server*" | Where {[datetime]::fromfiletime($_.pwdlastset) -lt $RefDate} |
$RefDate = (Get-Date).AddDays(-90)
Get-ADComputer -Filter * -Properties pwdlastset,OperatingSystem | Where OperatingSystem -like "*Server*" | Where {[datetime]::fromfiletime($_.pwdlastset) -lt $RefDate}
I hope you will find it helpful. Script should run on Windows Server 2012 and later..
Posted in
Windows Powershell,
Windows Server |
No Comment | 3,158 views | 30/06/2014 17:32
You can use following script to get Port and Fabric WWN information from FCinfo via PowerShell.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| # Get FCInfo Details
$FcToolCmd = "C:\StorageTools\fcinfo\fcinfo.exe /details"
# Create WWN Array
$WWNArray = @()
# Create Hash Table
$WWNInformation = @{}
# Port WWN Information
$FabricDetails = Invoke-Expression $FcToolCmd | Where {$_ -match "port_wwn"}
foreach ($FabricInfo in $FabricDetails)
{
# Get Port WWN
$FabricRegex = $FabricInfo -match "\b\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\b"
$PortWWN = $Matches[0]
# Add Hash Table
$WWNInformation."$PortWWN" = "NULL"
# Add WWN Array
$WWNArray += $PortWWN
}
# Fabric Index
$FabricIndex = 0;
# Fabric WWN Information
$FabricDetails = Invoke-Expression $FcToolCmd | Where {$_ -match "fabric"}
foreach ($FabricInfo in $FabricDetails)
{
# Get Fabric WWN
$FabricRegex = $FabricInfo -match "\b\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\b"
$FabricWWN = $Matches[0]
# Get Port WWN
$PortWWN = $WWNArray[$FabricIndex]
# Add Hash Table
$WWNInformation."$PortWWN" = "$FabricWWN"
# Update Fabric Index
$FabricIndex++
}
# Output Results
$WWNInformation |
# Get FCInfo Details
$FcToolCmd = "C:\StorageTools\fcinfo\fcinfo.exe /details"
# Create WWN Array
$WWNArray = @()
# Create Hash Table
$WWNInformation = @{}
# Port WWN Information
$FabricDetails = Invoke-Expression $FcToolCmd | Where {$_ -match "port_wwn"}
foreach ($FabricInfo in $FabricDetails)
{
# Get Port WWN
$FabricRegex = $FabricInfo -match "\b\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\b"
$PortWWN = $Matches[0]
# Add Hash Table
$WWNInformation."$PortWWN" = "NULL"
# Add WWN Array
$WWNArray += $PortWWN
}
# Fabric Index
$FabricIndex = 0;
# Fabric WWN Information
$FabricDetails = Invoke-Expression $FcToolCmd | Where {$_ -match "fabric"}
foreach ($FabricInfo in $FabricDetails)
{
# Get Fabric WWN
$FabricRegex = $FabricInfo -match "\b\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\:\S{2}\b"
$FabricWWN = $Matches[0]
# Get Port WWN
$PortWWN = $WWNArray[$FabricIndex]
# Add Hash Table
$WWNInformation."$PortWWN" = "$FabricWWN"
# Update Fabric Index
$FabricIndex++
}
# Output Results
$WWNInformation
That will give you a hashtable as a result, so you can see details.
Posted in
Windows Powershell,
Windows Server |
No Comment | 38,089 views | 27/06/2014 09:55
Following scripts require EMC Storage Integrator (ESI) PowerShell Toolkit (ESIPSToolkit).
Getting EMC Storage Snapshot Pools:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| Import-Module ESIPSToolkit
function Get-EMCStorageSnapPools {
$Storages = Get-EMCStorageSystem
foreach ($Storage in $Storages) {
$GlobalID = $Storage.GlobalID
$Snappool = Get-EMCSnapshotPool | Where StorageSystemGlobalId -eq $GlobalID
$Properties = New-Object Psobject
$Properties | Add-Member Noteproperty StorageName $Storage.UserFriendlyName
$Properties | Add-Member Noteproperty AvailableCapacity $Snappool.AvailableCapacity
$Properties | Add-Member Noteproperty UserCapacity $Snappool.UserCapacity
Write-Output $Properties
}
}
Get-EMCStorageSnapPools |
Import-Module ESIPSToolkit
function Get-EMCStorageSnapPools {
$Storages = Get-EMCStorageSystem
foreach ($Storage in $Storages) {
$GlobalID = $Storage.GlobalID
$Snappool = Get-EMCSnapshotPool | Where StorageSystemGlobalId -eq $GlobalID
$Properties = New-Object Psobject
$Properties | Add-Member Noteproperty StorageName $Storage.UserFriendlyName
$Properties | Add-Member Noteproperty AvailableCapacity $Snappool.AvailableCapacity
$Properties | Add-Member Noteproperty UserCapacity $Snappool.UserCapacity
Write-Output $Properties
}
}
Get-EMCStorageSnapPools
Getting Storage List:
1
2
3
| Import-Module ESIPSToolkit
$Storage = Get-EMCStorageSystem
$Storage.UserFriendlyName |
Import-Module ESIPSToolkit
$Storage = Get-EMCStorageSystem
$Storage.UserFriendlyName
Getting Storage Thin Pools:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| Import-Module ESIPSToolkit
function Get-EMCStorageThinPools {
$Storages = Get-EMCStorageSystem
foreach ($Storage in $Storages) {
$GlobalID = $Storage.GlobalID
$Thinpool = Get-EMCStoragePool | Where SupportsThinProvisioning -eq "True" | where StorageSystemGlobalId -eq $GlobalID
foreach ($Pool in $Thinpool) {
$Properties = New-Object Psobject
$Properties | Add-Member Noteproperty StorageName $storage.UserFriendlyName
$Properties | Add-Member Noteproperty PoolName $pool.Name
$Properties | Add-Member Noteproperty TotalCapacity $pool.TotalCapacity.ValueGB
$Properties | Add-Member Noteproperty AvailableCapacity $pool.AvailableCapacity.ValueGB
$Properties | Add-Member Noteproperty SubscribedCapacity $pool.SubscribedCapacity.ValueGB
Write-Output $Properties
}
}
}
Get-EMCStorageThinPools |
Import-Module ESIPSToolkit
function Get-EMCStorageThinPools {
$Storages = Get-EMCStorageSystem
foreach ($Storage in $Storages) {
$GlobalID = $Storage.GlobalID
$Thinpool = Get-EMCStoragePool | Where SupportsThinProvisioning -eq "True" | where StorageSystemGlobalId -eq $GlobalID
foreach ($Pool in $Thinpool) {
$Properties = New-Object Psobject
$Properties | Add-Member Noteproperty StorageName $storage.UserFriendlyName
$Properties | Add-Member Noteproperty PoolName $pool.Name
$Properties | Add-Member Noteproperty TotalCapacity $pool.TotalCapacity.ValueGB
$Properties | Add-Member Noteproperty AvailableCapacity $pool.AvailableCapacity.ValueGB
$Properties | Add-Member Noteproperty SubscribedCapacity $pool.SubscribedCapacity.ValueGB
Write-Output $Properties
}
}
}
Get-EMCStorageThinPools
Registering Host:
1
2
3
| $StorageArray = Get-EMCStorageSystem "CX4_1"
$HostRegistration = "C0:03:FF:00:00:FF:FF:00:C0:03:FF:65:4D:A6:00:00","C0:03:FF:00:00:FF:FF:00:C0:03:FF:37:25:4E:00:16"
$RegisterHost = New-EMCStorageRegisteredHost -StorageSystem $StorageArray -HostName "Server01" -IpAddress "192.168.0.114" -HostBusAdapterIds $HostRegistration |
$StorageArray = Get-EMCStorageSystem "CX4_1"
$HostRegistration = "C0:03:FF:00:00:FF:FF:00:C0:03:FF:65:4D:A6:00:00","C0:03:FF:00:00:FF:FF:00:C0:03:FF:37:25:4E:00:16"
$RegisterHost = New-EMCStorageRegisteredHost -StorageSystem $StorageArray -HostName "Server01" -IpAddress "192.168.0.114" -HostBusAdapterIds $HostRegistration
To be continued.. :)
Posted in
Virtual Machine Manager,
Windows Powershell,
Windows Server |
No Comment | 2,043 views | 24/06/2014 09:42
You can update all SCVMM agents with following script:
1
2
3
4
5
6
7
| $Credential = Get-SCRunAsAccount -Name "Domain_Account"
$HyperVHosts = Get-SCVMMManagedComputer
foreach ($HyperVHost in $HyperVHosts)
{
$ManagedComputer = Get-SCVMMManagedComputer -ComputerName $HyperVHost
Update-SCVMMManagedComputer -Credential $Credential -VMMManagedComputer $HyperVHost
} |
$Credential = Get-SCRunAsAccount -Name "Domain_Account"
$HyperVHosts = Get-SCVMMManagedComputer
foreach ($HyperVHost in $HyperVHosts)
{
$ManagedComputer = Get-SCVMMManagedComputer -ComputerName $HyperVHost
Update-SCVMMManagedComputer -Credential $Credential -VMMManagedComputer $HyperVHost
}
That will update all Hyper-V hosts agents as soon as possible.
Posted in
Windows Powershell,
Windows Server |
3 Comments | 1,998 views | 23/06/2014 11:44
This is third version of Hyper-V Cluster Memory Reports.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| $Clusters = Get-Content Clusters.txt
foreach ($Cluster in $Clusters)
{
[int]$TotalFreeMemory = 0;
[int]$TotalMemory = 0;
[int]$TotalUsedMemory = 0;
[int]$NodeCount = 0;
$ClusterNodes = Get-Cluster $Cluster | Get-ClusterNode
foreach ($ClusterNode in $ClusterNodes)
{
[int]$FreeMemory = [math]::round(((Get-WmiObject -ComputerName $ClusterNode -Class Win32_OperatingSystem).FreePhysicalMemory / 1MB), 0) - ([math]::round(((Get-WmiObject -ComputerName $ClusterNode -Class Win32_OperatingSystem).TotalVisibleMemorySize / 1MB), 0)*10/100)
[int]$TotalFreeMemory = [int]$TotalFreeMemory + [int]$FreeMemory
[int]$NodeMemory = [math]::round(((Get-WmiObject -ComputerName $ClusterNode -Class Win32_OperatingSystem).TotalVisibleMemorySize / 1MB), 0)
[int]$TotalMemory = [int]$TotalMemory + [int]$NodeMemory
[int]$UsedMemory = [int]$NodeMemory - [int]$FreeMemory
[int]$TotalUsedMemory = [int]$TotalUsedMemory + [int]$UsedMemory;
[int]$NodeCount = [int]$NodeCount + 1
}
[int]$TotalAvailableMemory = [int]$TotalFreeMemory - [int]$NodeMemory - ([int]$NodeMemory*10/100)
Write-Host "Cluster: $Cluster"
Write-Host "Total Memory: $TotalMemory"
Write-Host "Total Free Memory: $TotalFreeMemory"
Write-Host "Total Used Memory: $TotalUsedMemory"
Write-Host "Total Available Memory: $TotalAvailableMemory"
Write-Host "Node Count: $NodeCount"
Write-Host " "
$Value = $Cluster + ";" + $TotalMemory + ";" + $TotalFreeMemory + ";" + $TotalUsedMemory + ";" + $TotalAvailableMemory + ";" + $NodeCount + ";" + $NodeMemory
Add-Content -Value $Value -Path Memory.txt
} |
$Clusters = Get-Content Clusters.txt
foreach ($Cluster in $Clusters)
{
[int]$TotalFreeMemory = 0;
[int]$TotalMemory = 0;
[int]$TotalUsedMemory = 0;
[int]$NodeCount = 0;
$ClusterNodes = Get-Cluster $Cluster | Get-ClusterNode
foreach ($ClusterNode in $ClusterNodes)
{
[int]$FreeMemory = [math]::round(((Get-WmiObject -ComputerName $ClusterNode -Class Win32_OperatingSystem).FreePhysicalMemory / 1MB), 0) - ([math]::round(((Get-WmiObject -ComputerName $ClusterNode -Class Win32_OperatingSystem).TotalVisibleMemorySize / 1MB), 0)*10/100)
[int]$TotalFreeMemory = [int]$TotalFreeMemory + [int]$FreeMemory
[int]$NodeMemory = [math]::round(((Get-WmiObject -ComputerName $ClusterNode -Class Win32_OperatingSystem).TotalVisibleMemorySize / 1MB), 0)
[int]$TotalMemory = [int]$TotalMemory + [int]$NodeMemory
[int]$UsedMemory = [int]$NodeMemory - [int]$FreeMemory
[int]$TotalUsedMemory = [int]$TotalUsedMemory + [int]$UsedMemory;
[int]$NodeCount = [int]$NodeCount + 1
}
[int]$TotalAvailableMemory = [int]$TotalFreeMemory - [int]$NodeMemory - ([int]$NodeMemory*10/100)
Write-Host "Cluster: $Cluster"
Write-Host "Total Memory: $TotalMemory"
Write-Host "Total Free Memory: $TotalFreeMemory"
Write-Host "Total Used Memory: $TotalUsedMemory"
Write-Host "Total Available Memory: $TotalAvailableMemory"
Write-Host "Node Count: $NodeCount"
Write-Host " "
$Value = $Cluster + ";" + $TotalMemory + ";" + $TotalFreeMemory + ";" + $TotalUsedMemory + ";" + $TotalAvailableMemory + ";" + $NodeCount + ";" + $NodeMemory
Add-Content -Value $Value -Path Memory.txt
}
You should add your clusters into Clusters.txt file.