Compare commits
332 Commits
LucD-remar
...
rCisTag-mo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c50bef798 | ||
|
|
1739af675a | ||
|
|
c645366e5c | ||
|
|
2c2b16457c | ||
|
|
240394e2ed | ||
|
|
83463ba97e | ||
|
|
bb1869411c | ||
|
|
d6861d38fb | ||
|
|
d104a29393 | ||
|
|
cdfd510dd9 | ||
|
|
dc6b02a95a | ||
|
|
a47369a295 | ||
|
|
84503224b8 | ||
|
|
902899f067 | ||
|
|
e4245533cd | ||
|
|
2d429c6271 | ||
|
|
9f2fc3ec06 | ||
|
|
14256a32a8 | ||
|
|
ea1178a308 | ||
|
|
77d44734d4 | ||
|
|
02364c5687 | ||
|
|
6b4bbf562d | ||
|
|
9e588e39c9 | ||
|
|
d406e54b19 | ||
|
|
5879c10003 | ||
|
|
df32c59148 | ||
|
|
0b6d1dd793 | ||
|
|
ebf92d8130 | ||
|
|
e785ef98a4 | ||
|
|
7947f2c95e | ||
|
|
77adef309d | ||
|
|
dc523953ca | ||
|
|
76820423a4 | ||
|
|
c2f137c812 | ||
|
|
dfd5a4e37e | ||
|
|
1edf24432c | ||
|
|
78c91088f4 | ||
|
|
ba61e6bb0f | ||
|
|
ca6c566257 | ||
|
|
754e9300eb | ||
|
|
bfefc8d321 | ||
|
|
c0a851cc0b | ||
|
|
795bcccad8 | ||
|
|
accbd83eff | ||
|
|
e444ed58ef | ||
|
|
89de49c58f | ||
|
|
04aabda1ba | ||
|
|
7019556842 | ||
|
|
eeef520611 | ||
|
|
45192ff5ae | ||
|
|
677d0c211d | ||
|
|
038742d872 | ||
|
|
76556f26c2 | ||
|
|
6365ed0bd1 | ||
|
|
16530f256d | ||
|
|
e8896d388f | ||
|
|
3b3197b04a | ||
|
|
4f07508e42 | ||
|
|
78d606ab44 | ||
|
|
da2cf62c1b | ||
|
|
434d8c2b9b | ||
|
|
2a3eb898de | ||
|
|
a929b1a50c | ||
|
|
bcb2d21d64 | ||
|
|
9fe3a3ca85 | ||
|
|
40b34e3b21 | ||
|
|
24799047a2 | ||
|
|
5e9396c24f | ||
|
|
6c370b7f96 | ||
|
|
7375f0a53a | ||
|
|
22a611e538 | ||
|
|
0de5cbe2e0 | ||
|
|
fee53a0565 | ||
|
|
b10e560615 | ||
|
|
0d461ab72b | ||
|
|
2b9aa80b36 | ||
|
|
b8055b7ed8 | ||
|
|
b89bd7ab5a | ||
|
|
1ed68eeab2 | ||
|
|
fc90f81d88 | ||
|
|
e63f4178ab | ||
|
|
b21d2079ca | ||
|
|
cd98f8672d | ||
|
|
98997718b8 | ||
|
|
070de5d0bd | ||
|
|
b8d0d10716 | ||
|
|
5772d994f0 | ||
|
|
e70e50600f | ||
|
|
2960a00618 | ||
|
|
803a53991f | ||
|
|
11330a67ac | ||
|
|
630300e78d | ||
|
|
7e040bf18c | ||
|
|
30f199fe96 | ||
|
|
c0d0e9e441 | ||
|
|
2a7475e05a | ||
|
|
1172ebb2d3 | ||
|
|
d61cfc1b67 | ||
|
|
23b36d60a3 | ||
|
|
4c667eaf1f | ||
|
|
0abddc0c86 | ||
|
|
ca1f5a04d2 | ||
|
|
1424fea870 | ||
|
|
443888108b | ||
|
|
532738e180 | ||
|
|
0beda7c30d | ||
|
|
6ca366e8c4 | ||
|
|
704251045d | ||
|
|
0990bc0372 | ||
|
|
e1bc6912fa | ||
|
|
96a5ce3cee | ||
|
|
c723fdbd20 | ||
|
|
dc0213773d | ||
|
|
0f29eda365 | ||
|
|
5ba13716e9 | ||
|
|
390ce91bb4 | ||
|
|
d1560fbfaf | ||
|
|
88fc7740dc | ||
|
|
dcd74f6f6e | ||
|
|
6dab3ef94d | ||
|
|
99b8d1b32e | ||
|
|
d935c68224 | ||
|
|
c15b76c8d1 | ||
|
|
818f6ae53d | ||
|
|
acb0383f16 | ||
|
|
4936b79a5c | ||
|
|
8337b98633 | ||
|
|
3d0c65b802 | ||
|
|
6336f1b661 | ||
|
|
2a5b8b5ea1 | ||
|
|
ced9321130 | ||
|
|
70f7be0270 | ||
|
|
ae429792ed | ||
|
|
544cdbfea1 | ||
|
|
5e8896c925 | ||
|
|
81f0299bce | ||
|
|
e808a91fc5 | ||
|
|
6580d1b085 | ||
|
|
2769f885f3 | ||
|
|
0b0ecc4348 | ||
|
|
8c2915fc2d | ||
|
|
720595989a | ||
|
|
a20d1eda3e | ||
|
|
bc9c52d50b | ||
|
|
a3c91c6376 | ||
|
|
29578c6305 | ||
|
|
3c18981280 | ||
|
|
5aee669b4c | ||
|
|
bd2edd6bd9 | ||
|
|
fe738ba17a | ||
|
|
1b4ca3fb2e | ||
|
|
d1fc624c57 | ||
|
|
294863d495 | ||
|
|
a8dbe63929 | ||
|
|
cf6d2a4673 | ||
|
|
492f89cc91 | ||
|
|
a6f14b492b | ||
|
|
0038d751f0 | ||
|
|
530764394a | ||
|
|
94f8f19d84 | ||
|
|
10b540c8c8 | ||
|
|
373579a291 | ||
|
|
c5d19509c9 | ||
|
|
000c015714 | ||
|
|
86ebda35d4 | ||
|
|
f6aebe0c7b | ||
|
|
b885a9a394 | ||
|
|
60f4948ea7 | ||
|
|
dcf76d6b1a | ||
|
|
49834682a9 | ||
|
|
1fc4b37863 | ||
|
|
552793585a | ||
|
|
d55a16f19b | ||
|
|
0e037f19a4 | ||
|
|
7a919a49b9 | ||
|
|
4b711cca91 | ||
|
|
d4afcd2ab4 | ||
|
|
38baff0d31 | ||
|
|
e210b2f229 | ||
|
|
0d1c8c79c8 | ||
|
|
e3c9108ae8 | ||
|
|
fbbdb72300 | ||
|
|
2d6d3205e1 | ||
|
|
dd9723cf7b | ||
|
|
04985c7301 | ||
|
|
769401af81 | ||
|
|
f595e7e674 | ||
|
|
860b62df5b | ||
|
|
c5de6447f6 | ||
|
|
fd13b0b16d | ||
|
|
3f8d35a92a | ||
|
|
358337db74 | ||
|
|
e8298afe3a | ||
|
|
aae3d54c68 | ||
|
|
307f3d2997 | ||
|
|
a15c61cedf | ||
|
|
142e6361ef | ||
|
|
ce4dab7df6 | ||
|
|
42d33acb4c | ||
|
|
7ad1b05c29 | ||
|
|
dd8906d65f | ||
|
|
4ec117e6fe | ||
|
|
fa6c9f491f | ||
|
|
09648c7cc6 | ||
|
|
ea23bb0568 | ||
|
|
9fea4a97f3 | ||
|
|
6ede0e5aae | ||
|
|
9504abf440 | ||
|
|
c3d82c2119 | ||
|
|
a30d144974 | ||
|
|
1ceacb298d | ||
|
|
0c5518d439 | ||
|
|
dedb25c46e | ||
|
|
3f3bd0314e | ||
|
|
e658ebbe9a | ||
|
|
608ca60d34 | ||
|
|
c75d7926ec | ||
|
|
bc789d4bb6 | ||
|
|
9e71b2e44c | ||
|
|
804608f34a | ||
|
|
559db31aca | ||
|
|
e5fa15e227 | ||
|
|
58ba21aacd | ||
|
|
a393962595 | ||
|
|
7d49541a25 | ||
|
|
efcca6adc0 | ||
|
|
aad0b71b7e | ||
|
|
ce69869e8a | ||
|
|
df17793ede | ||
|
|
8b0750a94e | ||
|
|
4c647f4d1c | ||
|
|
9f8d094e38 | ||
|
|
7a5ae91379 | ||
|
|
554f6d691d | ||
|
|
9d145e91df | ||
|
|
8b57519fbb | ||
|
|
1977251e8f | ||
|
|
b49b3f9430 | ||
|
|
9d14a90183 | ||
|
|
1b41e22116 | ||
|
|
ad43f57a04 | ||
|
|
8201e075a4 | ||
|
|
8dee2ec498 | ||
|
|
d171b6e2c3 | ||
|
|
1d06122f4c | ||
|
|
f2b31ecd60 | ||
|
|
29bce56022 | ||
|
|
aee523fcb9 | ||
|
|
6967b1b7a6 | ||
|
|
64ff3657a9 | ||
|
|
ef1308c96e | ||
|
|
159c0821df | ||
|
|
2e2f027e2a | ||
|
|
a3bcc1e3b0 | ||
|
|
9c30b2953d | ||
|
|
9db2d0cbe6 | ||
|
|
69dcfb7d88 | ||
|
|
9b3db40de4 | ||
|
|
ca7fe938ab | ||
|
|
2eb47a6f92 | ||
|
|
02c66242f1 | ||
|
|
7eeece3d25 | ||
|
|
5dd7449b0e | ||
|
|
a202040013 | ||
|
|
147f97d0fa | ||
|
|
754f51326b | ||
|
|
284ba19d2f | ||
|
|
fd8ec98a44 | ||
|
|
43c80227b4 | ||
|
|
12d0d67c8b | ||
|
|
49bfa1a413 | ||
|
|
7a56f8ac30 | ||
|
|
47e0a453ad | ||
|
|
530b07d73e | ||
|
|
99b1c6bb1e | ||
|
|
a0d2450ff1 | ||
|
|
5bf60badf1 | ||
|
|
c2bd42eb6c | ||
|
|
7da4ea673b | ||
|
|
15484d0af5 | ||
|
|
f90d281930 | ||
|
|
fed74d9e02 | ||
|
|
2d594cb60d | ||
|
|
181add5bfd | ||
|
|
5d475bbd1b | ||
|
|
df5e47ac67 | ||
|
|
a316ba5dda | ||
|
|
3c686ecaba | ||
|
|
758b80f6b8 | ||
|
|
2a96855d03 | ||
|
|
e928f5b56a | ||
|
|
d7c5c17322 | ||
|
|
4b8e5dc46f | ||
|
|
19ff0ea26a | ||
|
|
f301e6c058 | ||
|
|
5ed2afd00d | ||
|
|
c566e68293 | ||
|
|
02a7183d3a | ||
|
|
764e77b9d5 | ||
|
|
067de29b30 | ||
|
|
48c4839be3 | ||
|
|
05f4069db5 | ||
|
|
c1c06b7afb | ||
|
|
002bf2b97a | ||
|
|
3cf6bf5d97 | ||
|
|
0b69b0dbe1 | ||
|
|
7f911cf268 | ||
|
|
4fd38aa645 | ||
|
|
c4d54cc42b | ||
|
|
37fb6e0d27 | ||
|
|
ea866993df | ||
|
|
f40ca375a1 | ||
|
|
153275f51b | ||
|
|
c39a39d8df | ||
|
|
99250732fb | ||
|
|
7bbec511cb | ||
|
|
b2ba87db86 | ||
|
|
7392e451c5 | ||
|
|
1489e86b66 | ||
|
|
7a38462f1a | ||
|
|
ddfb85780f | ||
|
|
06a3ea0210 | ||
|
|
172e1436c5 | ||
|
|
e1937544fb | ||
|
|
7f6482b7af | ||
|
|
f47c3a7c3b | ||
|
|
e91b0c0649 | ||
|
|
ca70d01e54 | ||
|
|
1dff599996 | ||
|
|
2e25d166a0 | ||
|
|
e709f1fdde | ||
|
|
c432a0d1fa |
0
.gitattributes
vendored
Normal file
0
.gitattributes
vendored
Normal file
51
.gitignore
vendored
Normal file
51
.gitignore
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# PowerShell Studio Files
|
||||
*.temppoint.*
|
||||
*.psproj.psbuild
|
||||
*.psbuild
|
||||
|
||||
#VS Code Files
|
||||
*.vscode
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# =========================
|
||||
# Operating System Files
|
||||
# =========================
|
||||
|
||||
# OSX
|
||||
# =========================
|
||||
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear on external disk
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
204
Modules/Backup-VCSA/Backup-VCSA.psm1
Normal file
204
Modules/Backup-VCSA/Backup-VCSA.psm1
Normal file
@@ -0,0 +1,204 @@
|
||||
Function Backup-VCSAToFile {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Graf
|
||||
Date: October 30, 2016
|
||||
Organization: VMware
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
This function will allow you to create a full or partial backup of your
|
||||
VCSA appliance. (vSphere 6.5 and higher)
|
||||
|
||||
.DESCRIPTION
|
||||
Use this function to backup your VCSA to a remote location
|
||||
|
||||
.EXAMPLE
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$BackupPassword = "VMw@re123"
|
||||
$Comment = "First API Backup"
|
||||
$LocationType = "FTP"
|
||||
$location = "10.144.99.5/vcsabackup-$((Get-Date).ToString('yyyy-MM-dd-hh-mm'))"
|
||||
$LocationUser = "admin"
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$locationPassword = "VMw@re123"
|
||||
PS C:\> Backup-VCSAToFile -BackupPassword $BackupPassword -LocationType $LocationType -Location $location -LocationUser $LocationUser -LocationPassword $locationPassword -Comment "This is a demo" -ShowProgress -FullBackup
|
||||
|
||||
|
||||
.NOTES
|
||||
Credit goes to @AlanRenouf for sharing the base of this function with me which I was able to take and make more robust as well as add in progress indicators
|
||||
You must be connected to the CisService for this to work, if you are not connected, the function will prompt you for your credentials
|
||||
If a -LocationType is not chosen, the function will default to FTP.
|
||||
The destination location for a backup must be an empty folder (easiest to use the get-date cmdlet in the location)
|
||||
-ShowProgress will give you a progressbar as well as updates in the console
|
||||
-CommonBackup will only backup the config whereas -Fullbackup grabs the historical data as well
|
||||
#>
|
||||
param (
|
||||
[Parameter(ParameterSetName=’FullBackup’)]
|
||||
[switch]$FullBackup,
|
||||
[Parameter(ParameterSetName=’CommonBackup’)]
|
||||
[switch]$CommonBackup,
|
||||
[ValidateSet('FTPS', 'HTTP', 'SCP', 'HTTPS', 'FTP')]
|
||||
$LocationType = "FTP",
|
||||
$Location,
|
||||
$LocationUser,
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$LocationPassword,
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$BackupPassword,
|
||||
$Comment = "Backup job",
|
||||
[switch]$ShowProgress
|
||||
)
|
||||
Begin {
|
||||
if (!($global:DefaultCisServers)){
|
||||
Add-Type -Assembly System.Windows.Forms
|
||||
[System.Windows.Forms.MessageBox]::Show("It appears you have not created a connection to the CisServer. You will now be prompted to enter your vCenter credentials to continue" , "Connect to CisServer") | out-null
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
} else {
|
||||
$Connection = $global:DefaultCisServers
|
||||
}
|
||||
if ($FullBackup) {$parts = @("common","seat")}
|
||||
if ($CommonBackup) {$parts = @("common")}
|
||||
}
|
||||
Process{
|
||||
$BackupAPI = Get-CisService com.vmware.appliance.recovery.backup.job
|
||||
$CreateSpec = $BackupAPI.Help.create.piece.CreateExample()
|
||||
$CreateSpec.parts = $parts
|
||||
$CreateSpec.backup_password = $BackupPassword
|
||||
$CreateSpec.location_type = $LocationType
|
||||
$CreateSpec.location = $Location
|
||||
$CreateSpec.location_user = $LocationUser
|
||||
$CreateSpec.location_password = $LocationPassword
|
||||
$CreateSpec.comment = $Comment
|
||||
try {
|
||||
$BackupJob = $BackupAPI.create($CreateSpec)
|
||||
}
|
||||
catch {
|
||||
throw $_.Exception.Message
|
||||
}
|
||||
|
||||
|
||||
If ($ShowProgress){
|
||||
do {
|
||||
$BackupAPI.get("$($BackupJob.ID)") | select id, progress, state
|
||||
$progress = ($BackupAPI.get("$($BackupJob.ID)").progress)
|
||||
Write-Progress -Activity "Backing up VCSA" -Status $BackupAPI.get("$($BackupJob.ID)").state -PercentComplete ($BackupAPI.get("$($BackupJob.ID)").progress) -CurrentOperation "$progress% Complete"
|
||||
start-sleep -seconds 5
|
||||
} until ($BackupAPI.get("$($BackupJob.ID)").progress -eq 100 -or $BackupAPI.get("$($BackupJob.ID)").state -ne "INPROGRESS")
|
||||
|
||||
Write-Progress -Activity "Backing up VCSA" -Completed
|
||||
$BackupAPI.get("$($BackupJob.ID)") | select id, progress, state
|
||||
}
|
||||
Else {
|
||||
$BackupJob | select id, progress, state
|
||||
}
|
||||
}
|
||||
End {}
|
||||
}
|
||||
|
||||
Function Get-VCSABackupJobs {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Graf
|
||||
Date: October 30, 2016
|
||||
Organization: VMware
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Get-VCSABackupJobs returns a list of all backup jobs VCSA has ever performed (vSphere 6.5 and higher)
|
||||
|
||||
.DESCRIPTION
|
||||
Get-VCSABackupJobs returns a list of all backup jobs VCSA has ever performed
|
||||
|
||||
.EXAMPLE
|
||||
PS C:\> Get-VCSABackupJobs
|
||||
|
||||
.NOTES
|
||||
The values returned are read as follows:
|
||||
YYYYMMDD-hhmmss-vcsabuildnumber
|
||||
You can pipe the results of this function into the Get-VCSABackupStatus function
|
||||
Get-VCSABackupJobs | select -First 1 | Get-VCSABackupStatus <- Most recent backup
|
||||
#>
|
||||
param (
|
||||
[switch]$ShowNewest
|
||||
)
|
||||
Begin {
|
||||
if (!($global:DefaultCisServers)){
|
||||
[System.Windows.Forms.MessageBox]::Show("It appears you have not created a connection to the CisServer. You will now be prompted to enter your vCenter credentials to continue" , "Connect to CisServer") | out-null
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
} else {
|
||||
$Connection = $global:DefaultCisServers
|
||||
}
|
||||
}
|
||||
Process{
|
||||
|
||||
$BackupAPI = Get-CisService com.vmware.appliance.recovery.backup.job
|
||||
|
||||
try {
|
||||
if ($ShowNewest) {
|
||||
$results = $BackupAPI.list()
|
||||
$results[0]
|
||||
} else {
|
||||
$BackupAPI.list()
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
End {}
|
||||
}
|
||||
|
||||
Function Get-VCSABackupStatus {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Graf
|
||||
Date: October 30, 2016
|
||||
Organization: VMware
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Returns the ID, Progress, and State of a VCSA backup (vSphere 6.5 and higher)
|
||||
|
||||
.DESCRIPTION
|
||||
Returns the ID, Progress, and State of a VCSA backup
|
||||
|
||||
.EXAMPLE
|
||||
PS C:\> $backups = Get-VCSABackupJobs
|
||||
$backups[0] | Get-VCSABackupStatus
|
||||
|
||||
.NOTES
|
||||
The BackupID can be piped in from the Get-VCSABackupJobs function and can return multiple job statuses
|
||||
#>
|
||||
Param (
|
||||
[parameter(ValueFromPipeline=$True)]
|
||||
[string[]]$BackupID
|
||||
)
|
||||
Begin {
|
||||
if (!($global:DefaultCisServers)){
|
||||
[System.Windows.Forms.MessageBox]::Show("It appears you have not created a connection to the CisServer. You will now be prompted to enter your vCenter credentials to continue" , "Connect to CisServer") | out-null
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
} else {
|
||||
$Connection = $global:DefaultCisServers
|
||||
}
|
||||
|
||||
$BackupAPI = Get-CisService com.vmware.appliance.recovery.backup.job
|
||||
}
|
||||
Process{
|
||||
|
||||
foreach ($id in $BackupID) {
|
||||
$BackupAPI.get("$id") | select id, progress, state
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
End {}
|
||||
}
|
||||
581
Modules/ContentLibrary/ContentLibrary.psm1
Normal file
581
Modules/ContentLibrary/ContentLibrary.psm1
Normal file
@@ -0,0 +1,581 @@
|
||||
Function Get-ContentLibrary {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function lists all available vSphere Content Libaries
|
||||
.PARAMETER LibraryName
|
||||
The name of a vSphere Content Library
|
||||
.EXAMPLE
|
||||
Get-ContentLibrary
|
||||
.EXAMPLE
|
||||
Get-ContentLibrary -LibraryName Test
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$false)][String]$LibraryName
|
||||
)
|
||||
|
||||
$contentLibaryService = Get-CisService com.vmware.content.library
|
||||
$libaryIDs = $contentLibaryService.list()
|
||||
|
||||
$results = @()
|
||||
foreach($libraryID in $libaryIDs) {
|
||||
$library = $contentLibaryService.get($libraryID)
|
||||
|
||||
# Use vCenter REST API to retrieve name of Datastore that is backing the Content Library
|
||||
$datastoreService = Get-CisService com.vmware.vcenter.datastore
|
||||
$datastore = $datastoreService.get($library.storage_backings.datastore_id)
|
||||
|
||||
if($library.publish_info.published) {
|
||||
$published = $library.publish_info.published
|
||||
$publishedURL = $library.publish_info.publish_url
|
||||
$externalReplication = $library.publish_info.persist_json_enabled
|
||||
} else {
|
||||
$published = $library.publish_info.published
|
||||
$publishedURL = "N/A"
|
||||
$externalReplication = "N/A"
|
||||
}
|
||||
|
||||
if($library.subscription_info) {
|
||||
$subscribeURL = $library.subscription_info.subscription_url
|
||||
$published = "N/A"
|
||||
} else {
|
||||
$subscribeURL = "N/A"
|
||||
}
|
||||
|
||||
if(!$LibraryName) {
|
||||
$libraryResult = [pscustomobject] @{
|
||||
Id = $library.Id;
|
||||
Name = $library.Name;
|
||||
Type = $library.Type;
|
||||
Description = $library.Description;
|
||||
Datastore = $datastore.name;
|
||||
Published = $published;
|
||||
PublishedURL = $publishedURL;
|
||||
JSONPersistence = $externalReplication;
|
||||
SubscribedURL = $subscribeURL;
|
||||
CreationTime = $library.Creation_Time;
|
||||
}
|
||||
$results+=$libraryResult
|
||||
} else {
|
||||
if($LibraryName -eq $library.name) {
|
||||
$libraryResult = [pscustomobject] @{
|
||||
Name = $library.Name;
|
||||
Id = $library.Id;
|
||||
Type = $library.Type;
|
||||
Description = $library.Description;
|
||||
Datastore = $datastore.name;
|
||||
Published = $published;
|
||||
PublishedURL = $publishedURL;
|
||||
JSONPersistence = $externalReplication;
|
||||
SubscribedURL = $subscribeURL;
|
||||
CreationTime = $library.Creation_Time;
|
||||
}
|
||||
$results+=$libraryResult
|
||||
}
|
||||
}
|
||||
}
|
||||
$results
|
||||
}
|
||||
|
||||
Function Get-ContentLibraryItems {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function lists all items within a given vSphere Content Library
|
||||
.PARAMETER LibraryName
|
||||
The name of a vSphere Content Library
|
||||
.PARAMETER LibraryItemName
|
||||
The name of a vSphere Content Library Item
|
||||
.EXAMPLE
|
||||
Get-ContentLibraryItems -LibraryName Test
|
||||
.EXAMPLE
|
||||
Get-ContentLibraryItems -LibraryName Test -LibraryItemName TinyPhotonVM
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$LibraryName,
|
||||
[Parameter(Mandatory=$false)][String]$LibraryItemName
|
||||
)
|
||||
|
||||
$contentLibaryService = Get-CisService com.vmware.content.library
|
||||
$libaryIDs = $contentLibaryService.list()
|
||||
|
||||
$results = @()
|
||||
foreach($libraryID in $libaryIDs) {
|
||||
$library = $contentLibaryService.get($libraryId)
|
||||
if($library.name -eq $LibraryName) {
|
||||
$contentLibaryItemService = Get-CisService com.vmware.content.library.item
|
||||
$itemIds = $contentLibaryItemService.list($libraryID)
|
||||
|
||||
foreach($itemId in $itemIds) {
|
||||
$item = $contentLibaryItemService.get($itemId)
|
||||
|
||||
if(!$LibraryItemName) {
|
||||
$itemResult = [pscustomobject] @{
|
||||
Name = $item.name;
|
||||
Id = $item.id;
|
||||
Description = $item.description;
|
||||
Size = $item.size
|
||||
Type = $item.type;
|
||||
Version = $item.version;
|
||||
MetadataVersion = $item.metadata_version;
|
||||
ContentVersion = $item.content_version;
|
||||
}
|
||||
$results+=$itemResult
|
||||
} else {
|
||||
if($LibraryItemName -eq $item.name) {
|
||||
$itemResult = [pscustomobject] @{
|
||||
Name = $item.name;
|
||||
Id = $item.id;
|
||||
Description = $item.description;
|
||||
Size = $item.size
|
||||
Type = $item.type;
|
||||
Version = $item.version;
|
||||
MetadataVersion = $item.metadata_version;
|
||||
ContentVersion = $item.content_version;
|
||||
}
|
||||
$results+=$itemResult
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$results
|
||||
}
|
||||
|
||||
Function Get-ContentLibraryItemFiles {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function lists all item files within a given vSphere Content Library
|
||||
.PARAMETER LibraryName
|
||||
The name of a vSphere Content Library
|
||||
.PARAMETER LibraryItemName
|
||||
The name of a vSphere Content Library Item
|
||||
.EXAMPLE
|
||||
Get-ContentLibraryItemFiles -LibraryName Test
|
||||
.EXAMPLE
|
||||
Get-ContentLibraryItemFiles -LibraryName Test -LibraryItemName TinyPhotonVM
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$LibraryName,
|
||||
[Parameter(Mandatory=$false)][String]$LibraryItemName
|
||||
)
|
||||
|
||||
$contentLibaryService = Get-CisService com.vmware.content.library
|
||||
$libaryIDs = $contentLibaryService.list()
|
||||
|
||||
$results = @()
|
||||
foreach($libraryID in $libaryIDs) {
|
||||
$library = $contentLibaryService.get($libraryId)
|
||||
if($library.name -eq $LibraryName) {
|
||||
$contentLibaryItemService = Get-CisService com.vmware.content.library.item
|
||||
$itemIds = $contentLibaryItemService.list($libraryID)
|
||||
|
||||
foreach($itemId in $itemIds) {
|
||||
$itemName = ($contentLibaryItemService.get($itemId)).name
|
||||
$contenLibraryItemFileSerice = Get-CisService com.vmware.content.library.item.file
|
||||
$files = $contenLibraryItemFileSerice.list($itemId)
|
||||
|
||||
foreach($file in $files) {
|
||||
if(!$LibraryItemName) {
|
||||
$fileResult = [pscustomobject] @{
|
||||
Name = $file.name;
|
||||
Version = $file.version;
|
||||
Size = $file.size;
|
||||
Stored = $file.cached;
|
||||
}
|
||||
$results+=$fileResult
|
||||
} else {
|
||||
if($itemName -eq $LibraryItemName) {
|
||||
$fileResult = [pscustomobject] @{
|
||||
Name = $file.name;
|
||||
Version = $file.version;
|
||||
Size = $file.size;
|
||||
Stored = $file.cached;
|
||||
}
|
||||
$results+=$fileResult
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$results
|
||||
}
|
||||
|
||||
Function Set-ContentLibrary {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function updates the JSON Persistence property for a given Content Library
|
||||
.PARAMETER LibraryName
|
||||
The name of a vSphere Content Library
|
||||
.EXAMPLE
|
||||
Set-ContentLibraryItems -LibraryName Test -JSONPersistenceEnabled
|
||||
.EXAMPLE
|
||||
Set-ContentLibraryItems -LibraryName Test -JSONPersistenceDisabled
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$LibraryName,
|
||||
[Parameter(Mandatory=$false)][Switch]$JSONPersistenceEnabled,
|
||||
[Parameter(Mandatory=$false)][Switch]$JSONPersistenceDisabled
|
||||
)
|
||||
|
||||
$contentLibaryService = Get-CisService com.vmware.content.library
|
||||
$libaryIDs = $contentLibaryService.list()
|
||||
|
||||
$found = $false
|
||||
foreach($libraryID in $libaryIDs) {
|
||||
$library = $contentLibaryService.get($libraryId)
|
||||
if($library.name -eq $LibraryName) {
|
||||
$found = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if($found) {
|
||||
$localLibraryService = Get-CisService -Name "com.vmware.content.local_library"
|
||||
|
||||
if($JSONPersistenceEnabled) {
|
||||
$jsonPersist = $true
|
||||
} else {
|
||||
$jsonPersist = $false
|
||||
}
|
||||
|
||||
$updateSpec = $localLibraryService.Help.update.update_spec.Create()
|
||||
$updateSpec.type = $library.type
|
||||
$updateSpec.publish_info.authentication_method = $library.publish_info.authentication_method
|
||||
$updateSpec.publish_info.persist_json_enabled = $jsonPersist
|
||||
Write-Host "Updating JSON Persistence configuration setting for $LibraryName ..."
|
||||
$localLibraryService.update($library.id,$updateSpec)
|
||||
} else {
|
||||
Write-Host "Unable to find Content Library $Libraryname"
|
||||
}
|
||||
}
|
||||
|
||||
Function New-ExtReplicatedContentLibrary {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function creates a new Subscriber Content Library from a JSON Persisted
|
||||
Content Library that has been externally replicated
|
||||
.PARAMETER LibraryName
|
||||
The name of the new vSphere Content Library
|
||||
.PARAMETER DatastoreName
|
||||
The name of the vSphere Datastore which contains JSON Persisted configuration file
|
||||
.PARAMETER SubscribeLibraryName
|
||||
The name fo the root directroy of the externally replicated Content Library residing on vSphere Datastore
|
||||
.PARAMETER AutoSync
|
||||
Whether or not to Automatically sync content
|
||||
.PARAMETER OnDemand
|
||||
Only sync content when requested
|
||||
.EXAMPLE
|
||||
New-ExtReplicatedContentLibrary -LibraryName Bar -DatastoreName iSCSI-02 -SubscribeLibraryName myExtReplicatedLibrary
|
||||
.EXAMPLE
|
||||
New-ExtReplicatedContentLibrary -LibraryName Bar -DatastoreName iSCSI-02 -SubscribeLibraryName myExtReplicatedLibrary -AutoSync $false -OnDemand $true
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$LibraryName,
|
||||
[Parameter(Mandatory=$true)][String]$DatastoreName,
|
||||
[Parameter(Mandatory=$true)][String]$SubscribeLibraryName,
|
||||
[Parameter(Mandatory=$false)][Boolean]$AutoSync=$false,
|
||||
[Parameter(Mandatory=$false)][Boolean]$OnDemand=$true
|
||||
)
|
||||
|
||||
$datastore = Get-Datastore -Name $DatastoreName
|
||||
|
||||
if($datastore) {
|
||||
$datastoreId = $datastore.ExtensionData.MoRef.Value
|
||||
$datastoreUrl = $datastore.ExtensionData.Info.Url
|
||||
$subscribeUrl = $datastoreUrl + $SubscribeLibraryName + "/lib.json"
|
||||
|
||||
$subscribeLibraryService = Get-CisService -Name "com.vmware.content.subscribed_library"
|
||||
|
||||
$StorageSpec = [pscustomobject] @{
|
||||
datastore_id = $datastoreId;
|
||||
type = "DATASTORE";
|
||||
}
|
||||
|
||||
$UniqueChangeId = [guid]::NewGuid().tostring()
|
||||
|
||||
$createSpec = $subscribeLibraryService.Help.create.create_spec.Create()
|
||||
$createSpec.name = $LibraryName
|
||||
$addResults = $createSpec.storage_backings.Add($StorageSpec)
|
||||
$createSpec.subscription_info.automatic_sync_enabled = $false
|
||||
$createSpec.subscription_info.on_demand = $true
|
||||
$createSpec.subscription_info.subscription_url = $subscribeUrl
|
||||
$createSpec.subscription_info.authentication_method = "NONE"
|
||||
$createSpec.type = "SUBSCRIBED"
|
||||
Write-Host "Creating new Externally Replicated Content Library called $LibraryName ..."
|
||||
$library = $subscribeLibraryService.create($UniqueChangeId,$createSpec)
|
||||
}
|
||||
}
|
||||
|
||||
Function Remove-SubscribedContentLibrary {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function deletes a Subscriber Content Library
|
||||
.PARAMETER LibraryName
|
||||
The name of the new vSphere Content Library to delete
|
||||
.EXAMPLE
|
||||
Remove-SubscribedContentLibrary -LibraryName Bar
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$LibraryName
|
||||
)
|
||||
|
||||
$contentLibaryService = Get-CisService com.vmware.content.library
|
||||
$libaryIDs = $contentLibaryService.list()
|
||||
|
||||
$found = $false
|
||||
foreach($libraryID in $libaryIDs) {
|
||||
$library = $contentLibaryService.get($libraryId)
|
||||
if($library.name -eq $LibraryName) {
|
||||
$found = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if($found) {
|
||||
$subscribeLibraryService = Get-CisService -Name "com.vmware.content.subscribed_library"
|
||||
|
||||
Write-Host "Deleting Subscribed Content Library $LibraryName ..."
|
||||
$subscribeLibraryService.delete($library.id)
|
||||
} else {
|
||||
Write-Host "Unable to find Content Library $LibraryName"
|
||||
}
|
||||
}
|
||||
|
||||
Function New-LocalContentLibrary {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function creates a new Subscriber Content Library from a JSON Persisted
|
||||
Content Library that has been externally replicated
|
||||
.PARAMETER LibraryName
|
||||
The name of the new vSphere Content Library
|
||||
.PARAMETER DatastoreName
|
||||
The name of the vSphere Datastore to store the Content Library
|
||||
.PARAMETER Publish
|
||||
Whther or not to publish the Content Library, this is required for JSON Peristence
|
||||
.PARAMETER JSONPersistence
|
||||
Whether or not to enable JSON Persistence which enables external replication of Content Library
|
||||
.EXAMPLE
|
||||
New-LocalContentLibrary -LibraryName Foo -DatastoreName iSCSI-01 -Publish $true
|
||||
.EXAMPLE
|
||||
New-LocalContentLibrary -LibraryName Foo -DatastoreName iSCSI-01 -Publish $true -JSONPersistence $true
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$LibraryName,
|
||||
[Parameter(Mandatory=$true)][String]$DatastoreName,
|
||||
[Parameter(Mandatory=$false)][Boolean]$Publish=$true,
|
||||
[Parameter(Mandatory=$false)][Boolean]$JSONPersistence=$false
|
||||
)
|
||||
|
||||
$datastore = Get-Datastore -Name $DatastoreName
|
||||
|
||||
if($datastore) {
|
||||
$datastoreId = $datastore.ExtensionData.MoRef.Value
|
||||
$localLibraryService = Get-CisService -Name "com.vmware.content.local_library"
|
||||
|
||||
$StorageSpec = [pscustomobject] @{
|
||||
datastore_id = $datastoreId;
|
||||
type = "DATASTORE";
|
||||
}
|
||||
|
||||
$UniqueChangeId = [guid]::NewGuid().tostring()
|
||||
|
||||
$createSpec = $localLibraryService.Help.create.create_spec.Create()
|
||||
$createSpec.name = $LibraryName
|
||||
$addResults = $createSpec.storage_backings.Add($StorageSpec)
|
||||
$createSpec.publish_info.authentication_method = "NONE"
|
||||
$createSpec.publish_info.persist_json_enabled = $JSONPersistence
|
||||
$createSpec.publish_info.published = $Publish
|
||||
$createSpec.type = "LOCAL"
|
||||
Write-Host "Creating new Local Content Library called $LibraryName ..."
|
||||
$library = $localLibraryService.create($UniqueChangeId,$createSpec)
|
||||
}
|
||||
}
|
||||
|
||||
Function Remove-LocalContentLibrary {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function deletes a Local Content Library
|
||||
.PARAMETER LibraryName
|
||||
The name of the new vSphere Content Library to delete
|
||||
.EXAMPLE
|
||||
Remove-LocalContentLibrary -LibraryName Bar
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$LibraryName
|
||||
)
|
||||
|
||||
$contentLibaryService = Get-CisService com.vmware.content.library
|
||||
$libaryIDs = $contentLibaryService.list()
|
||||
|
||||
$found = $false
|
||||
foreach($libraryID in $libaryIDs) {
|
||||
$library = $contentLibaryService.get($libraryId)
|
||||
if($library.name -eq $LibraryName) {
|
||||
$found = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if($found) {
|
||||
$localLibraryService = Get-CisService -Name "com.vmware.content.local_library"
|
||||
|
||||
Write-Host "Deleting Local Content Library $LibraryName ..."
|
||||
$localLibraryService.delete($library.id)
|
||||
} else {
|
||||
Write-Host "Unable to find Content Library $LibraryName"
|
||||
}
|
||||
}
|
||||
|
||||
Function Copy-ContentLibrary {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function copies all library items from one Content Library to another
|
||||
.PARAMETER SourceLibaryName
|
||||
The name of the source Content Library to copy from
|
||||
.PARAMETER DestinationLibaryName
|
||||
The name of the desintation Content Library to copy to
|
||||
.PARAMETER DeleteSourceFile
|
||||
Whther or not to delete library item from the source Content Library after copy
|
||||
.EXAMPLE
|
||||
Copy-ContentLibrary -SourceLibaryName Foo -DestinationLibaryName Bar
|
||||
.EXAMPLE
|
||||
Copy-ContentLibrary -SourceLibaryName Foo -DestinationLibaryName Bar -DeleteSourceFile $true
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$SourceLibaryName,
|
||||
[Parameter(Mandatory=$true)][String]$DestinationLibaryName,
|
||||
[Parameter(Mandatory=$false)][Boolean]$DeleteSourceFile=$false
|
||||
)
|
||||
|
||||
$sourceLibraryId = (Get-ContentLibrary -LibraryName $SourceLibaryName).Id
|
||||
if($sourceLibraryId -eq $null) {
|
||||
Write-Host -ForegroundColor red "Unable to find Source Content Library named $SourceLibaryName"
|
||||
exit
|
||||
}
|
||||
$destinationLibraryId = (Get-ContentLibrary -LibraryName $DestinationLibaryName).Id
|
||||
if($destinationLibraryId -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Unable to find Destination Content Library named $DestinationLibaryName"
|
||||
break
|
||||
}
|
||||
|
||||
$sourceItemFiles = Get-ContentLibraryItems -LibraryName $SourceLibaryName
|
||||
if($sourceItemFiles -eq $null) {
|
||||
Write-Host -ForegroundColor red "Unable to retrieve Content Library Items from $SourceLibaryName"
|
||||
break
|
||||
}
|
||||
|
||||
$contentLibaryItemService = Get-CisService com.vmware.content.library.item
|
||||
|
||||
foreach ($sourceItemFile in $sourceItemFiles) {
|
||||
# Check to see if file already exists in destination Content Library
|
||||
$result = Get-ContentLibraryItems -LibraryName $DestinationLibaryName -LibraryItemName $sourceItemFile.Name
|
||||
|
||||
if($result -eq $null) {
|
||||
# Create CopySpec
|
||||
$copySpec = $contentLibaryItemService.Help.copy.destination_create_spec.Create()
|
||||
$copySpec.library_id = $destinationLibraryId
|
||||
$copySpec.name = $sourceItemFile.Name
|
||||
$copySpec.description = $sourceItemFile.Description
|
||||
# Create random Unique Copy Id
|
||||
$UniqueChangeId = [guid]::NewGuid().tostring()
|
||||
|
||||
# Perform Copy
|
||||
try {
|
||||
Write-Host -ForegroundColor Cyan "Copying" $sourceItemFile.Name "..."
|
||||
$copyResult = $contentLibaryItemService.copy($UniqueChangeId, $sourceItemFile.Id, $copySpec)
|
||||
} catch {
|
||||
Write-Host -ForegroundColor Red "Failed to copy" $sourceItemFile.Name
|
||||
$Error[0]
|
||||
break
|
||||
}
|
||||
|
||||
# Delete source file if set to true
|
||||
if($DeleteSourceFile) {
|
||||
try {
|
||||
Write-Host -ForegroundColor Magenta "Deleteing" $sourceItemFile.Name "..."
|
||||
$deleteResult = $contentLibaryItemService.delete($sourceItemFile.Id)
|
||||
} catch {
|
||||
Write-Host -ForegroundColor Red "Failed to delete" $sourceItemFile.Name
|
||||
$Error[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Host -ForegroundColor Yellow "Skipping" $sourceItemFile.Name "already exists"
|
||||
|
||||
# Delete source file if set to true
|
||||
if($DeleteSourceFile) {
|
||||
try {
|
||||
Write-Host -ForegroundColor Magenta "Deleteing" $sourceItemFile.Name "..."
|
||||
$deleteResult = $contentLibaryItemService.delete($sourceItemFile.Id)
|
||||
} catch {
|
||||
Write-Host -ForegroundColor Red "Failed to delete" $sourceItemFile.Name
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
245
Modules/DatastoreFunctions/DatastoreFunctions.psm1
Normal file
245
Modules/DatastoreFunctions/DatastoreFunctions.psm1
Normal file
@@ -0,0 +1,245 @@
|
||||
<#
|
||||
.SYNOPSIS Datastore Functions
|
||||
.DESCRIPTION A collection of functions to manipulate datastore Mount + Attach status
|
||||
.EXAMPLE Get-Datastore | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
|
||||
.EXAMPLE Get-Datastore IX2ISCSI01 | Unmount-Datastore
|
||||
.EXAMPLE Get-Datastore IX2ISCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
|
||||
.EXAMPLE Get-Datastore IX2iSCSI01 | Mount-Datastore
|
||||
.EXAMPLE Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
|
||||
.EXAMPLE Get-Datastore IX2iSCSI01 | Detach-Datastore
|
||||
.EXAMPLE Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
|
||||
.EXAMPLE Get-Datastore IX2iSCSI01 | Attach-datastore
|
||||
.EXAMPLE Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
|
||||
.NOTES Written by Alan Renouf, originally published at https://blogs.vmware.com/vsphere/2012/01/automating-datastore-storage-device-detachment-in-vsphere-5.html
|
||||
.NOTES May 2017: Modified by Jason Coleman (virtuallyjason.blogspot.com), to improve performance when dealing with a large number of hosts and datastores
|
||||
#>
|
||||
Function Get-HostViews {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
$Datastore
|
||||
)
|
||||
Begin{
|
||||
$allDatastores = @()
|
||||
}
|
||||
Process {
|
||||
$allDatastores += $Datastore
|
||||
}
|
||||
End {
|
||||
#Build the array of Datastore Objects
|
||||
if (-not $Datastore) {
|
||||
$allDatastores = Get-Datastore
|
||||
}
|
||||
$allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
|
||||
if (-not $allDatastores){
|
||||
Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
|
||||
}
|
||||
$allHosts = @()
|
||||
$DShostsKeys = $allDatastores.extensiondata.host.key.value | sort | get-unique -asstring
|
||||
$DShosts = foreach ($thisKey in $DShostsKeys) {($allDatastores.extensiondata.host | ? {$_.key.value -eq $thisKey})[0]}
|
||||
$i = 1
|
||||
foreach ($DSHost in $DSHosts){
|
||||
write-progress -activity "Collecting ESXi Host Views" -status "Querying $($dshost.key)..." -percentComplete ($i++/$DSHosts.count*100)
|
||||
$hostObj = "" | select keyValue,hostView,storageSys
|
||||
$hostObj.hostView = get-view $DSHost.key
|
||||
$hostObj.keyValue = $DSHost.key.value
|
||||
$hostObj.storageSys = Get-View $hostObj.hostView.ConfigManager.StorageSystem
|
||||
$allHosts += $hostObj
|
||||
}
|
||||
write-progress -activity "Collecting ESXi Host Views" -completed
|
||||
$allHosts
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-DatastoreMountInfo {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
$Datastore
|
||||
)
|
||||
#Roll back up an unrolled array from a pipeline
|
||||
Begin{
|
||||
$allDatastores = @()
|
||||
}
|
||||
Process {
|
||||
$allDatastores += $Datastore
|
||||
}
|
||||
End {
|
||||
$AllInfo = @()
|
||||
#Build the array of Datastore Objects
|
||||
if (-not $Datastore) {
|
||||
$allDatastores = Get-Datastore
|
||||
}
|
||||
$allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
|
||||
if (-not $allDatastores){
|
||||
Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
|
||||
}
|
||||
$allDatastoreNAAs = foreach ($ds in $allDatastores) {$ds.ExtensionData.Info.vmfs.extent[0].diskname}
|
||||
|
||||
#Build the array of custom Host Objects
|
||||
$allHosts = Get-HostViews -datastore $allDatastores
|
||||
$output = @()
|
||||
$i = 1
|
||||
foreach ($dsHost in $allHosts){
|
||||
write-progress -activity "Checking Datastore access" -status "Checking $($dshost.hostview.name)..." -percentComplete ($i++ / $allHosts.count * 100)
|
||||
#Get all devices on the host that match the list of $allDatastoreNAAs
|
||||
$devices = $dsHost.storagesys.StorageDeviceInfo.ScsiLun
|
||||
foreach ($device in $devices){
|
||||
if ($allDatastoreNAAs -contains $device.canonicalName){
|
||||
#Record information about this device/host combo
|
||||
$thisDatastore = $alldatastores | ? {$_.ExtensionData.Info.vmfs.extent[0].diskname -eq $device.canonicalName}
|
||||
$hostviewDSAttachState = ""
|
||||
if ($device.operationalState[0] -eq "ok") {
|
||||
$hostviewDSAttachState = "Attached"
|
||||
} elseif ($device.operationalState[0] -eq "off") {
|
||||
$hostviewDSAttachState = "Detached"
|
||||
} else {
|
||||
$hostviewDSAttachState = $device.operationalstate[0]
|
||||
}
|
||||
$Info = "" | Select Datastore, VMHost, Lun, Mounted, State
|
||||
$Info.VMHost = $dsHost.hostview.name
|
||||
$Info.Datastore = $thisDatastore.name
|
||||
$Info.Lun = $device.canonicalName
|
||||
$Info.mounted = ($thisDatastore.extensiondata.host | ? {$_.key.value -eq $dshost.keyvalue}).mountinfo.mounted
|
||||
$Info.state = $hostviewDSAttachState
|
||||
$output += $info
|
||||
}
|
||||
}
|
||||
}
|
||||
write-progress -activity "Checking Datastore access" -completed
|
||||
$output
|
||||
}
|
||||
}
|
||||
|
||||
Function Detach-Datastore {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
$Datastore
|
||||
)
|
||||
Begin{
|
||||
$allDatastores = @()
|
||||
}
|
||||
Process {
|
||||
$allDatastores += $Datastore
|
||||
}
|
||||
End {
|
||||
$allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
|
||||
if (-not $allDatastores){
|
||||
Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
|
||||
}
|
||||
$allDatastoreNAAs = foreach ($ds in $allDatastores) {$ds.ExtensionData.Info.vmfs.extent[0].diskname}
|
||||
$allHosts = Get-HostViews -datastore $allDatastores
|
||||
$j = 1
|
||||
foreach ($dsHost in $allHosts){
|
||||
#Get all devices on the host that match the list of $allDatastoreNAAs
|
||||
write-progress -id 1 -activity "Detaching Datastores" -status "Removing device(s) from $($dsHost.hostview.name)" -percentComplete ($j++ / $allHosts.count * 100)
|
||||
$devices = $dsHost.storagesys.StorageDeviceInfo.ScsiLun | ? {$allDatastoreNAAs -contains $_.canonicalName}
|
||||
$i = 1
|
||||
foreach ($device in $devices){
|
||||
write-progress -parentid 1 -activity "Detaching Datastores" -status "Removing device: $(($allDatastores | ? {$_.ExtensionData.Info.vmfs.extent[0].diskname -eq $device.canonicalName}).name)" -percentComplete ($i++ / $allDatastoreNAAs.count * 100)
|
||||
$LunUUID = $Device.Uuid
|
||||
$dsHost.storageSys.DetachScsiLun($LunUUID);
|
||||
}
|
||||
}
|
||||
write-progress -activity "Detaching Datastores" -completed
|
||||
}
|
||||
}
|
||||
|
||||
Function Attach-Datastore {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
$Datastore
|
||||
)
|
||||
Begin{
|
||||
$allDatastores = @()
|
||||
}
|
||||
Process {
|
||||
$allDatastores += $Datastore
|
||||
}
|
||||
End {
|
||||
$allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
|
||||
if (-not $allDatastores){
|
||||
Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
|
||||
}
|
||||
$allDatastoreNAAs = foreach ($ds in $allDatastores) {$ds.ExtensionData.Info.vmfs.extent[0].diskname}
|
||||
$allHosts = Get-HostViews -datastore $allDatastores
|
||||
$j = 1
|
||||
foreach ($dsHost in $allHosts){
|
||||
#Get all devices on the host that match the list of $allDatastoreNAAs
|
||||
write-progress -id 1 -activity "Attaching Datastores" -status "Attaching devices to $($dsHost.hostview.name)" -percentComplete ($j++ / $allHosts.count * 100)
|
||||
$devices = $dsHost.storagesys.StorageDeviceInfo.ScsiLun
|
||||
$i = 1
|
||||
foreach ($device in $devices){
|
||||
write-progress -parentid 1 -activity "Attaching Datastores" -status "Attaching device: $($Device.Uuid)" -percentComplete ($i++ / $devices.count * 100)
|
||||
if ($allDatastoreNAAs -contains $device.canonicalName){
|
||||
$LunUUID = $Device.Uuid
|
||||
$dsHost.storageSys.AttachScsiLun($LunUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
write-progress -activity "Attaching Datastores" -completed
|
||||
}
|
||||
}
|
||||
|
||||
Function Unmount-Datastore {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
$Datastore
|
||||
)
|
||||
Begin{
|
||||
$allDatastores = @()
|
||||
}
|
||||
Process {
|
||||
$allDatastores += $Datastore
|
||||
}
|
||||
End {
|
||||
$allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
|
||||
if (-not $allDatastores){
|
||||
Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
|
||||
}
|
||||
$allHosts = Get-HostViews -datastore $allDatastores
|
||||
$j = 1
|
||||
foreach ($dsHost in $allHosts){
|
||||
write-progress -id 1 -activity "Unmounting Datastores" -status "Unmounting devices from $($dsHost.hostview.name)" -percentComplete ($j++ / $allHosts.count * 100)
|
||||
$i = 1
|
||||
foreach ($ds in $allDatastores){
|
||||
write-progress -parentid 1 -activity "Unmounting Datastores" -status "Unmounting device: $($ds.name)" -percentComplete ($i++ / $allDatastores.count * 100)
|
||||
$dsHost.storageSys.UnmountVmfsVolume($DS.ExtensionData.Info.vmfs.uuid);
|
||||
}
|
||||
}
|
||||
write-progress -activity "Unmounting Datastores" -completed
|
||||
}
|
||||
}
|
||||
|
||||
Function Mount-Datastore {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
$Datastore
|
||||
)
|
||||
Begin{
|
||||
$allDatastores = @()
|
||||
}
|
||||
Process {
|
||||
$allDatastores += $Datastore
|
||||
}
|
||||
End {
|
||||
$allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
|
||||
if (-not $allDatastores){
|
||||
Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
|
||||
}
|
||||
$allHosts = Get-HostViews -datastore $allDatastores
|
||||
$j = 0
|
||||
foreach ($dsHost in $allHosts){
|
||||
write-progress -activity "Mounting Datastores" -status "Mounting devices to $($dsHost.hostview.name)" -percentComplete ($j++ / $allHosts.count * 100)
|
||||
$i = 1
|
||||
foreach ($ds in $allDatastores){
|
||||
write-progress -activity "Mounting Datastores" -status "Mounting device: $($DS.ExtensionData.Info.vmfs.uuid)" -percentComplete ($i++ / $allDatastores.count * 100)
|
||||
$dsHost.storageSys.MountVmfsVolume($DS.ExtensionData.Info.vmfs.uuid);
|
||||
}
|
||||
}
|
||||
write-progress -activity "Mounting Datastores" -completed
|
||||
}
|
||||
}
|
||||
93
Modules/Get-NICDetails/Get-NICDetails.psm1
Normal file
93
Modules/Get-NICDetails/Get-NICDetails.psm1
Normal file
@@ -0,0 +1,93 @@
|
||||
function Get-NICDetails {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2017.02 ver 1.0 Base Release
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
-
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: ESXi 6.0 U2, ESXi 6.5
|
||||
PowerCLI Version: PowerCLI 6.3 R1, PowerCLI 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Server 2008 R2, Server 2012 R2
|
||||
Keyword: ESXi, NIC, vmnic, Driver, Firmware
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
Reports Firmware and Driver Details for your ESXi vmnics.
|
||||
|
||||
.Example
|
||||
Get-NICDetails -Clustername *
|
||||
|
||||
.PARAMETER Clustername
|
||||
Name or Wildcard of your vSphere Cluster Name to process.
|
||||
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0)]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Clustername
|
||||
|
||||
)
|
||||
|
||||
Begin {
|
||||
$Validate = $True
|
||||
|
||||
if (($myCluster = Get-Cluster -Name $Clustername).count -lt 1) {
|
||||
$Validate = $False
|
||||
thow "No Cluster '$myCluster' found!"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Process {
|
||||
|
||||
$MyView = @()
|
||||
if ($Validate -eq $True) {
|
||||
|
||||
foreach ($myVMhost in ($myCluster | Get-VMHost)) {
|
||||
|
||||
$esxcli2 = Get-ESXCLI -VMHost $myVMhost -V2
|
||||
$niclist = $esxcli2.network.nic.list.invoke()
|
||||
|
||||
$nicdetails = @()
|
||||
foreach ($nic in $niclist) {
|
||||
|
||||
$args = $esxcli2.network.nic.get.createargs()
|
||||
$args.nicname = $nic.name
|
||||
$nicdetail = $esxcli2.network.nic.get.Invoke($args)
|
||||
$nicdetails += $nicdetail
|
||||
|
||||
}
|
||||
ForEach ($nicdetail in $nicdetails){
|
||||
$NICReport = [PSCustomObject] @{
|
||||
Host = $myVMhost.Name
|
||||
vmnic = $nicdetail.Name
|
||||
LinkStatus = $nicdetail.LinkStatus
|
||||
BusInfo = $nicdetail.driverinfo.BusInfo
|
||||
Driver = $nicdetail.driverinfo.Driver
|
||||
FirmwareVersion = $nicdetail.driverinfo.FirmwareVersion
|
||||
DriverVersion = $nicdetail.driverinfo.Version
|
||||
}
|
||||
$MyView += $NICReport
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$MyView
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
131
Modules/Get-NewAndRemovedVMs/Get-NewAndRemovedVMs.psm1
Normal file
131
Modules/Get-NewAndRemovedVMs/Get-NewAndRemovedVMs.psm1
Normal file
@@ -0,0 +1,131 @@
|
||||
function Get-NewAndRemovedVMs {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.12 ver 1.0 Base Release
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
https://github.com/alanrenouf/vCheck-vSphere
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: 5.5 U2
|
||||
PowerCLI Version: PowerCLI 6.3 R1, PowerCLI 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Server 2012 R2
|
||||
===========================================================================
|
||||
Keywords vSphere, VM
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function report newly created and deleted VMs by Cluster.
|
||||
|
||||
.Example
|
||||
Get-NewAndRemovedVMs -ClusterName Cluster* | ft -AutoSize
|
||||
|
||||
.Example
|
||||
Get-NewAndRemovedVMs -ClusterName Cluster01 -Days 90
|
||||
|
||||
.PARAMETER ClusterName
|
||||
Name or Wildcard of your vSphere Cluster Name(s) to report.
|
||||
|
||||
.PARAMETER Day
|
||||
Range in Days to report.
|
||||
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0, HelpMessage = "Name or Wildcard of your vSphere Cluster Name to report")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String]$ClusterName,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=1, HelpMessage = "Range in Days to report")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String]$Days = "30"
|
||||
)
|
||||
Begin {
|
||||
function Get-VIEventPlus {
|
||||
|
||||
param(
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]$Entity,
|
||||
[string[]]$EventType,
|
||||
[DateTime]$Start,
|
||||
[DateTime]$Finish = (Get-Date),
|
||||
[switch]$Recurse,
|
||||
[string[]]$User,
|
||||
[Switch]$System,
|
||||
[string]$ScheduledTask,
|
||||
[switch]$FullMessage = $false,
|
||||
[switch]$UseUTC = $false
|
||||
)
|
||||
|
||||
process {
|
||||
$eventnumber = 100
|
||||
$events = @()
|
||||
$eventMgr = Get-View EventManager
|
||||
$eventFilter = New-Object VMware.Vim.EventFilterSpec
|
||||
$eventFilter.disableFullMessage = ! $FullMessage
|
||||
$eventFilter.entity = New-Object VMware.Vim.EventFilterSpecByEntity
|
||||
$eventFilter.entity.recursion = &{if($Recurse){"all"}else{"self"}}
|
||||
$eventFilter.eventTypeId = $EventType
|
||||
if($Start -or $Finish){
|
||||
$eventFilter.time = New-Object VMware.Vim.EventFilterSpecByTime
|
||||
if($Start){
|
||||
$eventFilter.time.beginTime = $Start
|
||||
}
|
||||
if($Finish){
|
||||
$eventFilter.time.endTime = $Finish
|
||||
}
|
||||
}
|
||||
if($User -or $System){
|
||||
$eventFilter.UserName = New-Object VMware.Vim.EventFilterSpecByUsername
|
||||
if($User){
|
||||
$eventFilter.UserName.userList = $User
|
||||
}
|
||||
if($System){
|
||||
$eventFilter.UserName.systemUser = $System
|
||||
}
|
||||
}
|
||||
if($ScheduledTask){
|
||||
$si = Get-View ServiceInstance
|
||||
$schTskMgr = Get-View $si.Content.ScheduledTaskManager
|
||||
$eventFilter.ScheduledTask = Get-View $schTskMgr.ScheduledTask |
|
||||
where {$_.Info.Name -match $ScheduledTask} |
|
||||
Select -First 1 |
|
||||
Select -ExpandProperty MoRef
|
||||
}
|
||||
if(!$Entity){
|
||||
$Entity = @(Get-Folder -NoRecursion)
|
||||
}
|
||||
$entity | %{
|
||||
$eventFilter.entity.entity = $_.ExtensionData.MoRef
|
||||
$eventCollector = Get-View ($eventMgr.CreateCollectorForEvents($eventFilter))
|
||||
$eventsBuffer = $eventCollector.ReadNextEvents($eventnumber)
|
||||
while($eventsBuffer){
|
||||
$events += $eventsBuffer
|
||||
$eventsBuffer = $eventCollector.ReadNextEvents($eventnumber)
|
||||
}
|
||||
$eventCollector.DestroyCollector()
|
||||
}
|
||||
if (-not $UseUTC)
|
||||
{
|
||||
$events | % { $_.createdTime = $_.createdTime.ToLocalTime() }
|
||||
}
|
||||
|
||||
$events
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process {
|
||||
$result = Get-VIEventPlus -Start ((get-date).adddays(-$Days)) -EventType @("VmCreatedEvent", "VmBeingClonedEvent", "VmBeingDeployedEvent","VmRemovedEvent")
|
||||
$sortedResult = $result | Select CreatedTime, @{N='Cluster';E={$_.ComputeResource.Name}}, @{Name="VMName";Expression={$_.vm.name}}, UserName, @{N='Type';E={$_.GetType().Name}}, FullFormattedMessage | Sort CreatedTime
|
||||
$sortedResult | where {$_.Cluster -like $ClusterName}
|
||||
}
|
||||
}
|
||||
114
Modules/Get-VMmaxIOPS/Get-VMmaxIOPS.psm1
Normal file
114
Modules/Get-VMmaxIOPS/Get-VMmaxIOPS.psm1
Normal file
@@ -0,0 +1,114 @@
|
||||
function Get-VMmaxIOPS {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.10 ver 1.0 Base Release
|
||||
2016.11 ver 1.1 Added vSphere 6.5 Support, New Counters, More Error Handling
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
http://www.lucd.info/2011/04/22/get-the-maximum-iops/
|
||||
https://communities.vmware.com/thread/485386
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: 5.5 U2, 6.5
|
||||
PowerCLI Version: PowerCLI 6.3 R1, 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Windows Server 2012 R2
|
||||
===========================================================================
|
||||
Keywords vSphere, ESXi, VM, Storage
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function will Create a VM Disk IOPS Report
|
||||
|
||||
.Example
|
||||
Get-VM TST* | Get-VMmaxIOPS -Minutes 60 | FT -Autosize
|
||||
|
||||
.Example
|
||||
$SampleVMs = Get-VM "TST*"
|
||||
Get-VMmaxIOPS -VMs $SampleVMs -Minutes 60
|
||||
|
||||
.PARAMETER VMs
|
||||
Specify the VMs
|
||||
|
||||
.PARAMETER Minutes
|
||||
Specify the Minutes to report (10080 is one Week)
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$True, Position=0)]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]] $VMs,
|
||||
[Parameter(Mandatory=$false, Position=1, HelpMessage = "Specify the Minutes to report (10080 is one Week)")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[int] $Minutes = 30
|
||||
)
|
||||
Begin {
|
||||
# none
|
||||
}
|
||||
Process {
|
||||
if ($_.PowerState -eq "PoweredOn") {
|
||||
#region: Global Definitions
|
||||
[int]$TimeRange = "-" + $Minutes
|
||||
#endregion
|
||||
|
||||
#region: Creating VM Stats
|
||||
Write-Verbose "$(Get-Date -Format G) Create VM Stats..."
|
||||
$VMMetrics = "virtualdisk.numberwriteaveraged.average","virtualdisk.numberreadaveraged.average"
|
||||
$Start = (Get-Date).AddMinutes($TimeRange)
|
||||
$stats = Get-Stat -Realtime -Stat $VMMetrics -Entity $VMs -Start $Start -Verbose:$False
|
||||
Write-Verbose "$(Get-Date -Format G) Create VM Stats completed"
|
||||
#endregion
|
||||
|
||||
#region: Creating HD-Tab
|
||||
Write-Verbose "$(Get-Date -Format G) Create HD Tab..."
|
||||
$hdTab = @{}
|
||||
foreach($hd in (Get-Harddisk -VM $VMs)){
|
||||
$controllerKey = $hd.Extensiondata.ControllerKey
|
||||
$controller = $hd.Parent.Extensiondata.Config.Hardware.Device | where{$_.Key -eq $controllerKey}
|
||||
$hdTab[$hd.Parent.Name + "/scsi" + $controller.BusNumber + ":" + $hd.Extensiondata.UnitNumber] = $hd.FileName.Split(']')[0].TrimStart('[')
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Create HD Tab completed"
|
||||
#endregion
|
||||
|
||||
#region: Creating Reports
|
||||
Write-Verbose "$(Get-Date -Format G) Create Report..."
|
||||
$reportPerf = @()
|
||||
$reportPerf = $stats | Group-Object -Property {$_.Entity.Name},Instance | %{
|
||||
New-Object PSObject -Property @{
|
||||
VM = $_.Values[0]
|
||||
Disk = $_.Values[1]
|
||||
IOPSWriteAvg = [math]::round( ($_.Group | `
|
||||
where{$_.MetricId -eq "virtualdisk.numberwriteaveraged.average"} | `
|
||||
Measure-Object -Property Value -Average).Average,2)
|
||||
IOPSReadAvg = [math]::round( ($_.Group | `
|
||||
where{$_.MetricId -eq "virtualdisk.numberreadaveraged.average"} | `
|
||||
Measure-Object -Property Value -Average).Average,2)
|
||||
Datastore = $hdTab[$_.Values[0] + "/"+ $_.Values[1]]
|
||||
}
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Create Report completed"
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
Else {
|
||||
Write-Error "VM $($_.Name) is Powered Off! Processing Skipped"
|
||||
}
|
||||
$reportPerf | Select-Object VM, Disk, Datastore, IOPSWriteAvg, IOPSReadAvg
|
||||
}
|
||||
|
||||
End {
|
||||
# none
|
||||
}
|
||||
|
||||
}
|
||||
234
Modules/Konfig-ESXi/Konfig-ESXi.psm1
Normal file
234
Modules/Konfig-ESXi/Konfig-ESXi.psm1
Normal file
@@ -0,0 +1,234 @@
|
||||
function Konfig-ESXi {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.12 ver 1.0 Base Release
|
||||
2016.12 ver 1.1 ESXi 6.5 Tests, Minor enhancements
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
Function My-Logger : http://www.virtuallyghetto.com/
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: ESXi 5.5 U2, ESXi 6.5
|
||||
PowerCLI Version: PowerCLI 6.3 R1, PowerCLI 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Server 2012 R2
|
||||
Keyword: ESXi, NTP, SSH, Syslog, SATP,
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function sets the Basic settings for a new ESXi.
|
||||
|
||||
* NTP
|
||||
* SSH
|
||||
* Syslog
|
||||
* Power Management
|
||||
* HP 3PAR SATP/PSP Rule
|
||||
* ...
|
||||
|
||||
.Example
|
||||
Konfig-ESXi -VMHost myesxi.lan.local -NTP 192.168.2.1, 192.168.2.2 -syslog "udp://loginsight.lan.local:514"
|
||||
|
||||
.PARAMETER VMHost
|
||||
Host to configure.
|
||||
|
||||
.PARAMETER NTP
|
||||
NTP Server(s) to set.
|
||||
|
||||
.PARAMETER Syslog
|
||||
Syslog Server to set, e.g. "udp://loginsight.lan.local:514"
|
||||
|
||||
DNS Name must be resolvable!
|
||||
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0)]
|
||||
[String] $VMHost,
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$False, Position=1)]
|
||||
[array]$NTP,
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$False, Position=2)]
|
||||
[String] $syslog
|
||||
|
||||
)
|
||||
|
||||
Begin {
|
||||
Function My-Logger {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]$message
|
||||
)
|
||||
|
||||
$timeStamp = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
|
||||
|
||||
Write-Host -NoNewline -ForegroundColor White "[$timestamp]"
|
||||
Write-Host -ForegroundColor Green " $message"
|
||||
}
|
||||
function Set-MyESXiOption {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0)]
|
||||
[String] $Name,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=1)]
|
||||
[String] $Value
|
||||
)
|
||||
process {
|
||||
$myESXiOption = Get-AdvancedSetting -Entity $ESXiHost -Name $Name
|
||||
if ($myESXiOption.Value -ne $Value) {
|
||||
My-Logger " Setting ESXi Option $Name to Value $Value"
|
||||
$myESXiOption | Set-AdvancedSetting -Value $Value -Confirm:$false | Out-Null
|
||||
}
|
||||
else {
|
||||
My-Logger " ESXi Option $Name already has Value $Value"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
$Validate = $True
|
||||
|
||||
#region: Start vCenter Connection
|
||||
My-Logger "Starting to Process ESXi Server Connection to $VMHost ..."
|
||||
if (($global:DefaultVIServers).count -gt 0) {
|
||||
Disconnect-VIServer -Force -Confirm:$False -ErrorAction SilentlyContinue
|
||||
}
|
||||
$VIConnection = Connect-VIServer -Server $VMHost
|
||||
if (-not $VIConnection.IsConnected) {
|
||||
Write-Error "ESXi Connection Failed."
|
||||
$Validate = $False
|
||||
}
|
||||
elseif ($VIConnection.ProductLine -ne "EmbeddedEsx") {
|
||||
Write-Error "Connencted System is not an ESXi."
|
||||
$Validate = $False
|
||||
}
|
||||
else {
|
||||
$ESXiHost = Get-VMHost
|
||||
My-Logger "Connected ESXi Version: $($ESXiHost.Version) $($ESXiHost.Build) "
|
||||
}
|
||||
#endregion
|
||||
|
||||
if ($Validate -eq $True) {
|
||||
|
||||
#region: Enable SSH and disable SSH Warning
|
||||
$SSHService = $ESXiHost | Get-VMHostService | where {$_.Key -eq 'TSM-SSH'}
|
||||
My-Logger "Starting SSH Service..."
|
||||
if($SSHService.Running -ne $True){
|
||||
Start-VMHostService -HostService $SSHService -Confirm:$false | Out-Null
|
||||
}
|
||||
else {
|
||||
My-Logger " SSH Service is already running"
|
||||
}
|
||||
My-Logger "Setting SSH Service to Automatic Start..."
|
||||
if($SSHService.Policy -ne "automatic"){
|
||||
Set-VMHostService -HostService $SSHService -Policy "Automatic" | Out-Null
|
||||
}
|
||||
else {
|
||||
My-Logger " SSH Service is already set to Automatic Start"
|
||||
}
|
||||
My-Logger "Disabling SSH Warning..."
|
||||
Set-MyESXiOption -Name "UserVars.SuppressShellWarning" -Value "1"
|
||||
#endregion
|
||||
|
||||
#region: Config NTP
|
||||
My-Logger "Removing existing NTP Server..."
|
||||
try {
|
||||
$ESXiHost | Remove-VMHostNtpServer -NtpServer (Get-VMHostNtpServer) -Confirm:$false
|
||||
}
|
||||
catch [System.Exception] {
|
||||
Write-Warning "Error during removing existing NTP Servers."
|
||||
}
|
||||
My-Logger "Setting new NTP Servers..."
|
||||
foreach ($myNTP in $NTP) {
|
||||
$ESXiHost | Add-VMHostNtpServer -ntpserver $myNTP -confirm:$False | Out-Null
|
||||
}
|
||||
|
||||
My-Logger "Configure NTP Service..."
|
||||
$NTPService = $ESXiHost | Get-VMHostService| Where-Object {$_.key -eq "ntpd"}
|
||||
if($NTPService.Running -eq $True){
|
||||
Stop-VMHostService -HostService $NTPService -Confirm:$false | Out-Null
|
||||
}
|
||||
if($NTPService.Policy -ne "on"){
|
||||
Set-VMHostService -HostService $NTPService -Policy "on" -confirm:$False | Out-Null
|
||||
}
|
||||
|
||||
My-Logger "Configure Local Time..."
|
||||
$HostTimeSystem = Get-View $ESXiHost.ExtensionData.ConfigManager.DateTimeSystem
|
||||
$HostTimeSystem.UpdateDateTime([DateTime]::UtcNow)
|
||||
|
||||
My-Logger "Start NTP Service..."
|
||||
Start-VMHostService -HostService $NTPService -confirm:$False | Out-Null
|
||||
#endregion
|
||||
|
||||
#region: Remove default PG
|
||||
My-Logger "Checking for Default Port Group ..."
|
||||
if ($defaultPG = $ESXiHost | Get-VirtualSwitch -Name vSwitch0 | Get-VirtualPortGroup -Name "VM Network" -ErrorAction SilentlyContinue ){
|
||||
Remove-VirtualPortGroup -VirtualPortGroup $defaultPG -confirm:$False | Out-Null
|
||||
My-Logger " Default PG Removed"
|
||||
}
|
||||
else {
|
||||
My-Logger " No Default PG found"
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region: Configure Static HighPower
|
||||
My-Logger "Setting PowerProfile to Static HighPower..."
|
||||
try {
|
||||
$HostView = ($ESXiHost | Get-View)
|
||||
(Get-View $HostView.ConfigManager.PowerSystem).ConfigurePowerPolicy(1)
|
||||
}
|
||||
catch [System.Exception] {
|
||||
Write-Warning "Error during Configure Static HighPower. See latest errors..."
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region: Conf Syslog
|
||||
My-Logger "Setting Syslog Firewall Rule ..."
|
||||
$SyslogFW = ($ESXiHost | Get-VMHostFirewallException | where {$_.Name -eq 'syslog'})
|
||||
if ($SyslogFW.Enabled -eq $False ){
|
||||
$SyslogFW | Set-VMHostFirewallException -Enabled:$true -Confirm:$false | Out-Null
|
||||
My-Logger " Syslog Firewall Rule enabled"
|
||||
}
|
||||
else {
|
||||
My-Logger " Syslog Firewall Rule already enabled"
|
||||
}
|
||||
My-Logger "Setting Syslog Server..."
|
||||
Set-MyESXiOption -Name "Syslog.global.logHost" -Value $syslog
|
||||
#endregion
|
||||
|
||||
#region: Change Disk Scheduler
|
||||
My-Logger "Changing Disk Scheduler..."
|
||||
Set-MyESXiOption -Name "Disk.SchedulerWithReservation" -Value "0"
|
||||
#endregion
|
||||
|
||||
#region: Configure HP 3PAR SATP/PSP Rule
|
||||
My-Logger "Configure HP 3PAR SATP/PSP Rule"
|
||||
$esxcli2 = Get-ESXCLI -VMHost $ESXiHost -V2
|
||||
$arguments = $esxcli2.storage.nmp.satp.rule.add.CreateArgs()
|
||||
$arguments.satp = "VMW_SATP_ALUA"
|
||||
$arguments.psp = "VMW_PSP_RR"
|
||||
$arguments.pspoption = "iops=100"
|
||||
$arguments.claimoption = "tpgs_on"
|
||||
$arguments.vendor = "3PARdata"
|
||||
$arguments.model = "VV"
|
||||
$arguments.description = "HP 3PAR custom SATP Claimrule"
|
||||
try {
|
||||
$esxcli2.storage.nmp.satp.rule.add.Invoke($arguments)
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Error during Configure HP 3PAR SATP/PSP Rule. See latest errors..."
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Modules/NSXT/NSXT.psd1
Normal file
18
Modules/NSXT/NSXT.psd1
Normal file
@@ -0,0 +1,18 @@
|
||||
@{
|
||||
ModuleToProcess = 'NSXT.psm1'
|
||||
ModuleVersion = '1.0.0.0'
|
||||
GUID = 'c72f4e3d-5d1d-498f-ba86-6fa03e4ae6dd'
|
||||
Author = 'William Lam'
|
||||
CompanyName = 'primp-industries.com'
|
||||
Copyright = '(c) 2017. All rights reserved.'
|
||||
Description = 'Powershell Module for NSX-T REST API Functions'
|
||||
PowerShellVersion = '5.0'
|
||||
FunctionsToExport = 'Get-NSXTComputeManager','Get-NSXTFabricNode','Get-NSXTFirewallRule','Get-NSXTIPPool','Get-NSXTLogicalSwitch','Get-NSXTManager','Get-NSXTTransportZone','Get-NSXTController'
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
Tags = @('NSX-T','REST')
|
||||
LicenseUri = 'https://www.tldrlegal.com/l/mit'
|
||||
ProjectUri = 'https://github.com/lamw/PowerCLI-Example-Scripts/tree/master/Modules/NSXT'
|
||||
}
|
||||
}
|
||||
}
|
||||
260
Modules/NSXT/NSXT.psm1
Normal file
260
Modules/NSXT/NSXT.psm1
Normal file
@@ -0,0 +1,260 @@
|
||||
Function Get-NSXTController {
|
||||
Param (
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
|
||||
)
|
||||
|
||||
$clusterNodeService = Get-NsxtService -Name "com.vmware.nsx.cluster.nodes"
|
||||
$clusterNodeStatusService = Get-NsxtService -Name "com.vmware.nsx.cluster.nodes.status"
|
||||
if($Id) {
|
||||
$nodes = $clusterNodeService.get($Id)
|
||||
} else {
|
||||
$nodes = $clusterNodeService.list().results | where { $_.manager_role -eq $null }
|
||||
}
|
||||
|
||||
$results = @()
|
||||
foreach ($node in $nodes) {
|
||||
$nodeId = $node.id
|
||||
$nodeName = $node.controller_role.control_plane_listen_addr.ip_address
|
||||
$nodeStatusResults = $clusterNodeStatusService.get($nodeId)
|
||||
|
||||
$tmp = [pscustomobject] @{
|
||||
Id = $nodeId;
|
||||
Name = $nodeName;
|
||||
ClusterStatus = $nodeStatusResults.control_cluster_status.control_cluster_status;
|
||||
Version = $nodeStatusResults.version;
|
||||
|
||||
}
|
||||
$results+=$tmp
|
||||
}
|
||||
$results
|
||||
}
|
||||
|
||||
Function Get-NSXTFabricNode {
|
||||
Param (
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id,
|
||||
[Switch]$ESXi,
|
||||
[Switch]$Edge
|
||||
)
|
||||
|
||||
$fabricNodeService = Get-NsxtService -Name "com.vmware.nsx.fabric.nodes"
|
||||
$fabricNodeStatusService = Get-NsxtService -Name "com.vmware.nsx.fabric.nodes.status"
|
||||
if($Id) {
|
||||
$nodes = $fabricNodeService.get($Id)
|
||||
} else {
|
||||
if($ESXi) {
|
||||
$nodes = $fabricNodeService.list().results | where { $_.resource_type -eq "HostNode" }
|
||||
} elseif ($Edge) {
|
||||
$nodes = $fabricNodeService.list().results | where { $_.resource_type -eq "EdgeNode" }
|
||||
} else {
|
||||
$nodes = $fabricNodeService.list().results
|
||||
}
|
||||
}
|
||||
|
||||
$results = @()
|
||||
foreach ($node in $nodes) {
|
||||
$nodeStatusResult = $fabricNodeStatusService.get($node.id)
|
||||
|
||||
$tmp = [pscustomobject] @{
|
||||
Id = $node.id;
|
||||
Name = $node.display_name;
|
||||
Type = $node.resource_type;
|
||||
Address = $node.ip_addresses;
|
||||
NSXVersion = $nodeStatusResult.software_version
|
||||
OS = $node.os_type;
|
||||
Version = $node.os_version;
|
||||
Status = $nodeStatusResult.host_node_deployment_status
|
||||
ManagerStatus = $nodeStatusResult.mpa_connectivity_status
|
||||
ControllerStatus = $nodeStatusResult.lcp_connectivity_status
|
||||
}
|
||||
$results+=$tmp
|
||||
}
|
||||
$results
|
||||
}
|
||||
|
||||
Function Get-NSXTIPPool {
|
||||
Param (
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
|
||||
)
|
||||
|
||||
$ipPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools"
|
||||
|
||||
if($Id) {
|
||||
$ipPools = $ipPoolService.get($Id)
|
||||
} else {
|
||||
$ipPools = $ipPoolService.list().results
|
||||
}
|
||||
|
||||
$results = @()
|
||||
foreach ($ipPool in $ipPools) {
|
||||
$tmp = [pscustomobject] @{
|
||||
Id = $ipPool.Id;
|
||||
Name = $ipPool.Display_Name;
|
||||
Total = $ipPool.pool_usage.total_ids;
|
||||
Free = $ipPool.pool_usage.free_ids;
|
||||
Network = $ipPool.subnets.cidr;
|
||||
Gateway = $ipPool.subnets.gateway_ip;
|
||||
DNS = $ipPool.subnets.dns_nameservers;
|
||||
RangeStart = $ipPool.subnets.allocation_ranges.start;
|
||||
RangeEnd = $ipPool.subnets.allocation_ranges.end
|
||||
}
|
||||
$results+=$tmp
|
||||
}
|
||||
$results
|
||||
}
|
||||
|
||||
Function Get-NSXTTransportZone {
|
||||
Param (
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
|
||||
)
|
||||
|
||||
$transportZoneService = Get-NsxtService -Name "com.vmware.nsx.transport_zones"
|
||||
|
||||
if($Id) {
|
||||
$transportZones = $transportZoneService.get($Id)
|
||||
} else {
|
||||
$transportZones = $transportZoneService.list().results
|
||||
}
|
||||
|
||||
$results = @()
|
||||
foreach ($transportZone in $transportZones) {
|
||||
$tmp = [pscustomobject] @{
|
||||
Id = $transportZone.Id;
|
||||
Name = $transportZone.display_name;
|
||||
Type = $transportZone.transport_type;
|
||||
HostSwitchName = $transportZone.host_switch_name;
|
||||
}
|
||||
$results+=$tmp
|
||||
}
|
||||
$results
|
||||
}
|
||||
|
||||
Function Get-NSXTComputeManager {
|
||||
Param (
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
|
||||
)
|
||||
|
||||
$computeManagerSerivce = Get-NsxtService -Name "com.vmware.nsx.fabric.compute_managers"
|
||||
$computeManagerStatusService = Get-NsxtService -Name "com.vmware.nsx.fabric.compute_managers.status"
|
||||
|
||||
if($Id) {
|
||||
$computeManagers = $computeManagerSerivce.get($id)
|
||||
} else {
|
||||
$computeManagers = $computeManagerSerivce.list().results
|
||||
}
|
||||
|
||||
$results = @()
|
||||
foreach ($computeManager in $computeManagers) {
|
||||
$computeManagerStatus = $computeManagerStatusService.get($computeManager.Id)
|
||||
|
||||
$tmp = [pscustomobject] @{
|
||||
Id = $computeManager.Id;
|
||||
Name = $computeManager.display_name;
|
||||
Server = $computeManager.server
|
||||
Type = $computeManager.origin_type;
|
||||
Version = $computeManagerStatus.Version;
|
||||
Registration = $computeManagerStatus.registration_status;
|
||||
Connection = $computeManagerStatus.connection_status;
|
||||
}
|
||||
$results+=$tmp
|
||||
}
|
||||
$results
|
||||
}
|
||||
|
||||
Function Get-NSXTLogicalSwitch {
|
||||
Param (
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
|
||||
)
|
||||
|
||||
$logicalSwitchService = Get-NsxtService -Name "com.vmware.nsx.logical_switches"
|
||||
$logicalSwitchSummaryService = Get-NsxtService -Name "com.vmware.nsx.logical_switches.summary"
|
||||
|
||||
if($Id) {
|
||||
$logicalSwitches = $logicalSwitchService.get($Id)
|
||||
} else {
|
||||
$logicalSwitches = $logicalSwitchService.list().results
|
||||
}
|
||||
|
||||
$results = @()
|
||||
foreach ($logicalSwitch in $logicalSwitches) {
|
||||
$transportZone = (Get-NSXTTransportZone -Id $logicalSwitch.transport_zone_id | Select Name | ft -HideTableHeaders | Out-String).trim()
|
||||
$ports = $logicalSwitchSummaryService.get($logicalSwitch.id).num_logical_ports
|
||||
|
||||
$tmp = [pscustomobject] @{
|
||||
Id = $logicalSwitch.Id;
|
||||
Name = $logicalSwitch.display_name;
|
||||
VLAN = $logicalSwitch.vlan;
|
||||
AdminStatus = $logicalSwitch.admin_state;
|
||||
Ports = $ports;
|
||||
TransportZone = $transportZone;
|
||||
}
|
||||
$results+=$tmp
|
||||
}
|
||||
$results
|
||||
}
|
||||
|
||||
Function Get-NSXTFirewallRule {
|
||||
Param (
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
|
||||
)
|
||||
|
||||
$firewallService = Get-NsxtService -Name "com.vmware.nsx.firewall.sections"
|
||||
$firewallRuleService = Get-NsxtService -Name "com.vmware.nsx.firewall.sections.rules"
|
||||
|
||||
if($Id) {
|
||||
$firewallRuleSections = $firewallService.get($Id)
|
||||
} else {
|
||||
$firewallRuleSections = $firewallService.list().results
|
||||
}
|
||||
|
||||
$sectionResults = @()
|
||||
foreach ($firewallRuleSection in $firewallRuleSections) {
|
||||
$tmp = [pscustomobject] @{
|
||||
Id = $firewallRuleSection.Id;
|
||||
Name = $firewallRuleSection.display_name;
|
||||
Type = $firewallRuleSection.section_type;
|
||||
Stateful = $firewallRuleSection.stateful;
|
||||
RuleCount = $firewallRuleSection.rule_count;
|
||||
}
|
||||
$sectionResults+=$tmp
|
||||
}
|
||||
$sectionResults
|
||||
|
||||
$firewallResults = @()
|
||||
if($id) {
|
||||
$firewallRules = $firewallRuleService.list($id).results
|
||||
foreach ($firewallRule in $firewallRules) {
|
||||
$tmp = [pscustomobject] @{
|
||||
Id = $firewallRule.id;
|
||||
Name = $firewallRule.display_name;
|
||||
Sources = if($firewallRule.sources -eq $null) { "ANY" } else { $firewallRule.sources};
|
||||
Destination = if($firewallRule.destinations -eq $null) { "ANY" } else { $firewallRule.destinations };
|
||||
Services = if($firewallRule.services -eq $null) { "ANY" } else { $firewallRule.services } ;
|
||||
Action = $firewallRule.action;
|
||||
AppliedTo = if($firewallRule.applied_tos -eq $null) { "ANY" } else { $firewallRule.applied_tos };
|
||||
Log = $firewallRule.logged;
|
||||
}
|
||||
$firewallResults+=$tmp
|
||||
}
|
||||
}
|
||||
$firewallResults
|
||||
}
|
||||
|
||||
Function Get-NSXTManager {
|
||||
$clusterNodeService = Get-NsxtService -Name "com.vmware.nsx.cluster.nodes"
|
||||
|
||||
$nodes = $clusterNodeService.list().results
|
||||
|
||||
$results = @()
|
||||
foreach ($node in $nodes) {
|
||||
if($node.manager_role -ne $null) {
|
||||
$tmp = [pscustomobject] @{
|
||||
Id = $node.id;
|
||||
Name = $node.display_name;
|
||||
Address = $node.appliance_mgmt_listen_addr;
|
||||
SHA256Thumbprint = $node.manager_role.api_listen_addr.certificate_sha256_thumbprint;
|
||||
}
|
||||
$results+=$tmp
|
||||
}
|
||||
}
|
||||
$results
|
||||
}
|
||||
123
Modules/PSvLIMessage/PSvLIMessage.psm1
Normal file
123
Modules/PSvLIMessage/PSvLIMessage.psm1
Normal file
@@ -0,0 +1,123 @@
|
||||
add-type @"
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
public class TrustAllCertsPolicy : ICertificatePolicy {
|
||||
public bool CheckValidationResult(
|
||||
ServicePoint srvPoint, X509Certificate certificate,
|
||||
WebRequest request, int certificateProblem) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
"@
|
||||
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
|
||||
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Organization: Private
|
||||
Personal Blog: mycloudrevolution.com
|
||||
Twitter: @vMarkus_K
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vRealize Log Insight 3.3.1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Server 2012 R2
|
||||
Keyword: vRealize, RestAPI
|
||||
|
||||
Dependencies:
|
||||
PowerCLI Version: PowerCLI 6.3 R1
|
||||
|
||||
.SYNOPSIS
|
||||
Push Messages to VMware vRealize Log Insight.
|
||||
|
||||
.DESCRIPTION
|
||||
Creates a Messages in VMware vRealize Log Insight via the Ingestion API
|
||||
|
||||
.EXAMPLE
|
||||
Push-vLIMessage -vLIServer "loginsight.lan.local" -vLIAgentID "12862842-5A6D-679C-0E38-0E2BE888BB28" -Text "My Test"
|
||||
|
||||
.EXAMPLE
|
||||
Push-vLIMessage -vLIServer "loginsight.lan.local" -vLIAgentID "12862842-5A6D-679C-0E38-0E2BE888BB28" -Text "My Test" -Hostname MyTEST -FieldName myTest -FieldContent myTest
|
||||
|
||||
.PARAMETER vLIServer
|
||||
Specify the FQDN of your vRealize Log Insight Appliance
|
||||
|
||||
.PARAMETER vLIAgentID
|
||||
Specify the vRealize Log Insight Agent ID, e.g. "12862842-5A6D-679C-0E38-0E2BE888BB28"
|
||||
|
||||
.PARAMETER Text
|
||||
Specify the Event Text
|
||||
|
||||
.PARAMETER Hostname
|
||||
Specify the Hostanme displayed in vRealize Log Insight
|
||||
|
||||
.PARAMETER FieldName
|
||||
Specify the a Optional Field Name for vRealize Log Insight
|
||||
|
||||
.PARAMETER FieldContent
|
||||
Specify the a Optional FieldContent for the Field in -FieldName for vRealize Log Insight
|
||||
If FielName is missing and FieldContent is given, it will be ignored
|
||||
|
||||
#Requires PS -Version 3.0
|
||||
|
||||
#>
|
||||
function Push-vLIMessage {
|
||||
|
||||
[cmdletbinding()]
|
||||
param (
|
||||
[parameter(Mandatory=$true)]
|
||||
[string]$Text,
|
||||
[parameter(Mandatory=$true)]
|
||||
[string]$vLIServer,
|
||||
[parameter(Mandatory=$true)]
|
||||
[string]$vLIAgentID,
|
||||
[parameter(Mandatory=$false)]
|
||||
[string]$Hostname = $env:computername,
|
||||
[parameter(Mandatory=$false)]
|
||||
[string]$FieldName,
|
||||
[parameter(Mandatory=$false)]
|
||||
[string]$FieldContent = ""
|
||||
)
|
||||
Process {
|
||||
$Field_vLI = [ordered]@{
|
||||
name = "PS_vLIMessage"
|
||||
content = "true"
|
||||
}
|
||||
$Field_HostName = [ordered]@{
|
||||
name = "hostname"
|
||||
content = $Hostname
|
||||
}
|
||||
|
||||
$Fields = @($Field_vLI, $Field_HostName)
|
||||
|
||||
if ($FieldName) {
|
||||
$Field_Custom = [ordered]@{
|
||||
name = $FieldName
|
||||
content = $FieldContent
|
||||
}
|
||||
$Fields += @($Field_Custom)
|
||||
}
|
||||
|
||||
$Restcall = @{
|
||||
messages = ([Object[]]([ordered]@{
|
||||
text = ($Text)
|
||||
fields = ([Object[]]$Fields)
|
||||
}))
|
||||
} | convertto-json -Depth 4
|
||||
|
||||
$Resturl = ("http://" + $vLIServer + ":9000/api/v1/messages/ingest/" + $vLIAgentID)
|
||||
try
|
||||
{
|
||||
$Response = Invoke-RestMethod $Resturl -Method Post -Body $Restcall -ContentType 'application/json' -ErrorAction stop
|
||||
Write-Information "REST Call to Log Insight server successful"
|
||||
Write-Verbose $Response
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Error "REST Call failed to Log Insight server"
|
||||
Write-Verbose $error[0]
|
||||
Write-Verbose $Resturl
|
||||
}
|
||||
}
|
||||
}
|
||||
468
Modules/ProactiveHA/ProactiveHA.psm1
Normal file
468
Modules/ProactiveHA/ProactiveHA.psm1
Normal file
@@ -0,0 +1,468 @@
|
||||
Function New-PHAProvider {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to register a new Proactive HA Provider with vCenter Server
|
||||
.PARAMETER ProviderName
|
||||
Name of ProactiveHA Provider
|
||||
.PARAMETER ComponentType
|
||||
Name of a supported ComponentType that ProactiveHA supports (Fan, Memory, Network, Power or Storage)
|
||||
.PARAMETER ComponentDescription
|
||||
Description of the health check for the given component
|
||||
.PARAMETER ComponentId
|
||||
Unique identifier for the given component within a ProactiveHA Provider
|
||||
.EXAMPLE
|
||||
New-PHAProvider -ProviderName "virtuallyGhetto" -ComponentType Power -ComponentDescription "Simulated ProactiveHA Provider" -ComponentId "Power"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderName,
|
||||
[Parameter(Mandatory=$true)][ValidateSet("Fan","Memory","Network","Power","Storage")][String]$ComponentType,
|
||||
[Parameter(Mandatory=$true)][String]$ComponentDescription,
|
||||
[Parameter(Mandatory=$true)][String]$ComponentId
|
||||
)
|
||||
Write-Host -ForegroundColor Red "`n******************** DISCLAIMER ********************"
|
||||
Write-Host -ForegroundColor Red "**** THIS IS NOT INTENDED FOR PRODUCTION USE ****"
|
||||
Write-Host -ForegroundColor Red "**** LEARNING PURPOSES ONLY ****"
|
||||
Write-Host -ForegroundColor Red "******************** DISCLAIMER ********************`n"
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$healthInfo = [VMware.Vim.HealthUpdateInfo] @{
|
||||
ComponentType = $ComponentType
|
||||
description = $ComponentDescription
|
||||
Id = $ComponentId
|
||||
}
|
||||
|
||||
try {
|
||||
Write-Host "`nRegistering new Proactive HA Provider $ProviderName ..."
|
||||
$providerId = $healthManager.RegisterHealthUpdateProvider($ProviderName,$healthInfo)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-PHAProvider {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to return list of all Proactive HA Providers registered with vCenter Server
|
||||
.EXAMPLE
|
||||
Get-PHAProvider
|
||||
#>
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$healthProviderResults = @()
|
||||
$hpIDs = $healthManager.QueryProviderList()
|
||||
|
||||
foreach ($hpID in $hpIDs) {
|
||||
$hpName = $healthManager.QueryProviderName($hpID)
|
||||
$hpConfig = $healthManager.QueryHealthUpdateInfos($hpID)
|
||||
|
||||
$hp = [pscustomobject] @{
|
||||
ProviderName = $hpName
|
||||
ProviderID = $hpID
|
||||
ComponentType = $hpConfig.componentType
|
||||
ComponentID = $hpConfig.id
|
||||
Description = $hpConfig.description
|
||||
}
|
||||
$healthProviderResults+=$hp
|
||||
}
|
||||
$healthProviderResults
|
||||
}
|
||||
|
||||
Function Remove-PHAProvider {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to remove a registered Proactive HA Provider from vCenter Server
|
||||
.PARAMETER ProviderId
|
||||
The ProactiveHA provider ID (retrieved from Get-PHAProvider) to unregister
|
||||
.EXAMPLE
|
||||
Remove-PHAProvider -ProviderID "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderId
|
||||
)
|
||||
|
||||
Write-Host -ForegroundColor Red "`n******************** DISCLAIMER ********************"
|
||||
Write-Host -ForegroundColor Red "**** THIS IS NOT INTENDED FOR PRODUCTION USE ****"
|
||||
Write-Host -ForegroundColor Red "**** LEARNING PURPOSES ONLY ****"
|
||||
Write-Host -ForegroundColor Red "******************** DISCLAIMER ********************`n"
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
try {
|
||||
Write-Host "`nUnregistering Proactive HA Provider $ProviderId ... "
|
||||
$healthManager.UnregisterHealthUpdateProvider($providerId)
|
||||
} catch {
|
||||
if($Error[0].Exception.InnerException.MethodFault.getType().Name -eq "InvalidState") {
|
||||
Write-host -ForegroundColor Red "The Proactive HA Provider is still in use, please disable it before unregistering"
|
||||
} else {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Set-PHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to enable/disable Proactive HA for vSphere Cluster
|
||||
.PARAMETER Cluster
|
||||
Name of the vSphere Cluster to enable Proactive HA
|
||||
.PARAMETER ProviderId
|
||||
Proactive HA Provider ID to enable in vSphere Cluster
|
||||
.PARAMETER ClusterMode
|
||||
Whether Proactive HA should be "Automated" or "Manual" for actions it will take
|
||||
.PARAMETER ModerateRemediation
|
||||
Type of operation (Maintenance Mode or Quaratine Mode) to perform when a Moderate issue is observed
|
||||
.PARAMETER SevereRemediation
|
||||
Type of operation (Maintenance Mode or Quaratine Mode) to perform when a Severe issue is observed
|
||||
.EXAMPLE
|
||||
Set-PHAConfig -Cluster VSAN-Cluster -Enabled -ClusterMode Automated -ModerateRemediation QuarantineMode -SevereRemediation QuarantineMode -ProviderID "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
.EXAMPLE
|
||||
Set-PHAConfig -Cluster VSAN-Cluster -Disabled -ProviderID "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderId,
|
||||
[Parameter(Mandatory=$true)][String]$Cluster,
|
||||
[Parameter(Mandatory=$false)][ValidateSet("Automated","Manual")]$ClusterMode="Manual",
|
||||
[Parameter(Mandatory=$false)][ValidateSet("MaintenanceMode","QuarantineMode")]$ModerateRemediation="QuarantineMode",
|
||||
[Parameter(Mandatory=$false)][ValidateSet("MaintenanceMode","QuarantineMode")]$SevereRemediation="QuarantineMode",
|
||||
[Switch]$Enabled,
|
||||
[Switch]$Disabled
|
||||
)
|
||||
|
||||
$ClusterView = Get-View -ViewType ClusterComputeResource -Property Name,Host,ConfigurationEx -Filter @{"Name" = $Cluster}
|
||||
|
||||
if($ClusterView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster $cluster ..."
|
||||
break
|
||||
}
|
||||
|
||||
$vmhosts = $ClusterView.host
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
if($Enabled) {
|
||||
try {
|
||||
$entities = @()
|
||||
foreach ($vmhost in $vmhosts) {
|
||||
if(-not $healthManager.HasMonitoredEntity($ProviderId,$vmhost)) {
|
||||
$entities += $vmhost
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Enabling Proactive HA monitoring for all ESXi hosts in cluster ..."
|
||||
$healthManager.AddMonitoredEntities($ProviderId,$entities)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
|
||||
try {
|
||||
$healthProviders = @()
|
||||
|
||||
# Make sure not to remove existing ProactiveHA providers
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$currentHPs = $ClusterView.ConfigurationEx.infraUpdateHaConfig.providers
|
||||
foreach ($currentHP in $currentHPs) {
|
||||
$healthProviders+=$currentHP
|
||||
}
|
||||
if(-not ($healthProviders -contains $ProviderID)) {
|
||||
$healthProviders+=$ProviderId
|
||||
}
|
||||
} else {
|
||||
$healthProviders+=$ProviderId
|
||||
}
|
||||
|
||||
$PHASpec = [VMware.Vim.ClusterInfraUpdateHaConfigInfo] @{
|
||||
enabled = $true
|
||||
behavior = $ClusterMode
|
||||
moderateRemediation = $ModerateRemediation
|
||||
severeRemediation = $SevereRemediation
|
||||
providers = $healthProviders
|
||||
}
|
||||
|
||||
$spec = [VMware.Vim.ClusterConfigSpecEx] @{
|
||||
infraUpdateHaConfig = $PHASpec
|
||||
}
|
||||
|
||||
Write-Host "Enabling Proactive HA Provider $ProviderId on $Cluster ..."
|
||||
$task = $ClusterView.ReconfigureComputeResource_Task($spec,$True)
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task | Out-Null
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
|
||||
if($Disabled) {
|
||||
foreach ($vmhost in $vmhosts) {
|
||||
if($vmhost.runtime.inQuarantineMode) {
|
||||
Write-Host -ForegroundColor Red $vmhost.name " is currently still in Quaratine Mode, please remediate this before disabling Proactive HA"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$healthProviders = @()
|
||||
|
||||
# Make sure not to remove existing ProactiveHA providers
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$currentHPs = $ClusterView.ConfigurationEx.infraUpdateHaConfig.providers
|
||||
foreach ($currentHP in $currentHPs) {
|
||||
if($currentHP -ne $ProviderId) {
|
||||
$healthProviders+=$currentHP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$PHASpec = [VMware.Vim.ClusterInfraUpdateHaConfigInfo] @{
|
||||
enabled = $true
|
||||
behavior = $ClusterMode
|
||||
moderateRemediation = $ModerateRemediation
|
||||
severeRemediation = $SevereRemediation
|
||||
providers = $healthProviders
|
||||
}
|
||||
|
||||
$spec = [VMware.Vim.ClusterConfigSpecEx] @{
|
||||
infraUpdateHaConfig = $PHASpec
|
||||
}
|
||||
|
||||
Write-Host "Disabling Proactive HA Provider $ProviderId on $Cluster ..."
|
||||
$task = $ClusterView.ReconfigureComputeResource_Task($spec,$True)
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task | Out-Null
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
|
||||
$ClusterView.UpdateViewData()
|
||||
|
||||
try {
|
||||
$entities = @()
|
||||
foreach ($vmhost in $vmhosts) {
|
||||
if($healthManager.HasMonitoredEntity($ProviderId,$vmhost)) {
|
||||
$entities += $vmhost
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Disabling Proactive HA monitoring for all ESXi hosts in cluster ..."
|
||||
$healthManager.RemoveMonitoredEntities($ProviderId,$entities)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-PHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to retrieve Proactive HA configuration for a vSphere Cluster
|
||||
.PARAMETER Cluster
|
||||
Name of the vSphere Cluster to check Proactive HA configuration
|
||||
.EXAMPLE
|
||||
Get-PHAConfig -Cluster VSAN-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$Cluster
|
||||
)
|
||||
|
||||
$ClusterView = Get-View -ViewType ClusterComputeResource -Property Name,ConfigurationEx -Filter @{"Name" = $Cluster}
|
||||
|
||||
if($ClusterView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster $cluster ..."
|
||||
break
|
||||
}
|
||||
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$phSettings = $ClusterView.ConfigurationEx.InfraUpdateHaConfig
|
||||
$providers = $ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers
|
||||
$healthProviders = @()
|
||||
foreach ($provider in $providers) {
|
||||
$providerName = $healthManager.QueryProviderName($provider)
|
||||
$healthProviders+=$providerName
|
||||
}
|
||||
|
||||
$pHAConfig = [pscustomobject] @{
|
||||
Enabled = $phSettings.Enabled
|
||||
ClusterMode = $phSettings.behavior
|
||||
ModerateRemediation = $phSettings.ModerateRemediation
|
||||
SevereRemediation = $phSettings.SevereRemediation
|
||||
HealthProviders = $healthProviders
|
||||
}
|
||||
$pHAConfig
|
||||
} else {
|
||||
Write-Host "Proactive HA has not been configured on this vSphere Cluster"
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-PHAHealth {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to retrieve the Proactive HA health info for all ESXi hosts in vSphere Cluster
|
||||
.PARAMETER Cluster
|
||||
Name of the vSphere Cluster to check Proactive HA health information
|
||||
.EXAMPLE
|
||||
Get-PHAHealth -Cluster VSAN-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$Cluster
|
||||
)
|
||||
|
||||
$ClusterView = Get-View -ViewType ClusterComputeResource -Property Name,ConfigurationEx -Filter @{"Name" = $Cluster}
|
||||
|
||||
if($ClusterView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster $cluster ..."
|
||||
break
|
||||
}
|
||||
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$providers = $ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers
|
||||
|
||||
foreach ($provider in $providers) {
|
||||
$providerName = $healthManager.QueryProviderName($provider)
|
||||
$healthUpdates = $healthManager.QueryHealthUpdates($provider)
|
||||
|
||||
$healthResults = @()
|
||||
Write-Host -NoNewline -ForegroundColor Magenta "Health summary for Proactive HA Provider $providerName`:`n"
|
||||
foreach ($healthUpdate in $healthUpdates) {
|
||||
$vmhost = Get-View $healthUpdate.Entity
|
||||
|
||||
$hr = [PSCustomObject] @{
|
||||
Entity = $vmhost.name
|
||||
Status = $healthUpdate.status
|
||||
HealthComponentId = $healthUpdate.HealthUpdateInfoId
|
||||
HealthUpdateId = $healthUpdate.Id
|
||||
Remediation = $healthUpdate.Remediation
|
||||
}
|
||||
$healthResults+=$hr
|
||||
}
|
||||
$healthResults
|
||||
}
|
||||
} else {
|
||||
Write-Host "Proactive HA has not been configured on this vSphere Cluster"
|
||||
}
|
||||
}
|
||||
|
||||
Function New-PHASimulation {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to return VCHA Configuration
|
||||
.PARAMETER ProviderId
|
||||
The Proactive HA Provider ID that you like to simulate a health update from
|
||||
.PARAMETER EsxiHost
|
||||
The name of ESXi host to update the health on
|
||||
.PARAMETER Component
|
||||
The name of the matching component ID from Proactive HA Provider to simulate a health update from
|
||||
.PARAMETER HealthStatus
|
||||
The health value (green, yellow or red) for the given simulated health Update
|
||||
.PARAMETER Remediation
|
||||
The remediation message associated with simulated health update
|
||||
.EXAMPLE
|
||||
New-PHASimulation -EsxiHost vesxi65-4.primp-industries.com -Component Power -HealthStatus green -Remediation "" -ProviderId "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
.EXAMPLE
|
||||
New-PHASimulation -EsxiHost vesxi65-4.primp-industries.com -Component Power -HealthStatus red -Remediation "Please replace my virtual PSU" -ProviderId "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderId,
|
||||
[Parameter(Mandatory=$true)][String]$EsxiHost,
|
||||
[Parameter(Mandatory=$true)][String]$Component,
|
||||
[Parameter(Mandatory=$true)][ValidateSet("green","red","yellow")][String]$HealthStatus,
|
||||
[Parameter(Mandatory=$false)][String]$Remediation
|
||||
)
|
||||
|
||||
Write-Host -ForegroundColor Red "`n******************** DISCLAIMER ********************"
|
||||
Write-Host -ForegroundColor Red "**** THIS IS NOT INTENDED FOR PRODUCTION USE ****"
|
||||
Write-Host -ForegroundColor Red "**** LEARNING PURPOSES ONLY ****"
|
||||
Write-Host -ForegroundColor Red "******************** DISCLAIMER ********************`n"
|
||||
|
||||
$vmhost = Get-View -ViewType HostSystem -Property Name -Filter @{"name" = $EsxiHost}
|
||||
|
||||
if($vmhost -eq $null) {
|
||||
Write-Host -ForegroundColor Red "`nUnable to find ESXi host $EsxiHost ..."
|
||||
break
|
||||
}
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
# Randomly generating an ID for Health Update
|
||||
# In general, you would want to generate a specific ID
|
||||
# which can be referenced between ProactiveHA Provider
|
||||
# and VMware logs for troubleshooting purposes
|
||||
$HealthUpdateID = "vghetto-" + (Get-Random -Minimum 1 -Maximum 100000)
|
||||
|
||||
# All other Health Status can have a remediation message
|
||||
# but for green, it must be an empty string or API call will fail
|
||||
if($HealthStatus -eq "green") {
|
||||
$Remediation = ""
|
||||
}
|
||||
|
||||
$healthUpdate = [VMware.Vim.HealthUpdate] @{
|
||||
Entity = $vmhost.moref
|
||||
HealthUpdateInfoId = $Component
|
||||
Id = $HealthUpdateId
|
||||
Status = $HealthStatus
|
||||
Remediation = $Remediation
|
||||
}
|
||||
|
||||
try {
|
||||
Write-Host "`nSimulating Proactive HA Health Update to ..."
|
||||
Write-Host "`tHost: $EsxiHost "
|
||||
Write-Host -NoNewline "`tStatus: "
|
||||
Write-Host -ForegroundColor $HealthStatus "$HealthStatus"
|
||||
Write-Host "`tRemediation Messsage: $Remediation"
|
||||
$healthManager.PostHealthUpdates($providerId,$healthUpdate)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
227
Modules/Recommend-Sizing/Recommend-Sizing.psm1
Normal file
227
Modules/Recommend-Sizing/Recommend-Sizing.psm1
Normal file
@@ -0,0 +1,227 @@
|
||||
function Recommend-Sizing {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.11 ver 1.0 Base Release
|
||||
2016.11 ver 1.1 Optional Stats Collection
|
||||
2016.11 ver 1.2 VM Stats from Realtime Data and new Counters
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
http://www.lucd.info/2011/04/22/get-the-maximum-iops/
|
||||
https://communities.vmware.com/thread/485386
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: 5.5 U2, 6.0
|
||||
PowerCLI Version: PowerCLI 6.3 R1, PowerCLI 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Server 2012 R2
|
||||
===========================================================================
|
||||
Keywords vSphere, ESXi, VM, Storage, Sizing
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function collects Basic vSphere Informations for a Hardware Sizing Recommandation. Focus is in Compute Ressources.
|
||||
|
||||
.Example
|
||||
Recommend-Sizing -ClusterNames Cluster01, Cluster02 -Stats -StatsRange 60 -Verbose
|
||||
|
||||
.Example
|
||||
Recommend-Sizing -ClusterNames Cluster01, Cluster02
|
||||
|
||||
.Example
|
||||
Recommend-Sizing -ClusterNames Cluster01
|
||||
|
||||
.PARAMETER ClusterNames
|
||||
List of your vSphere Cluser Names to process.
|
||||
|
||||
.PARAMETER Stats
|
||||
Enables Stats Collection.
|
||||
|
||||
Warning: At the moment this is only fully tested with vSphere 5.5 and vSphere 6.5!
|
||||
|
||||
.PARAMETER StatsRange
|
||||
Time Range in Minutes for the Stats Collection.
|
||||
Default is 24h.
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0)]
|
||||
[Array] $ClusterNames,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=1, ParameterSetName = "Stats")]
|
||||
[switch] $Stats,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=2, ParameterSetName = "Stats")]
|
||||
[int] $StatsRange = 1440
|
||||
|
||||
)
|
||||
Begin {
|
||||
if ($Stats) {
|
||||
Write-Warning "Stats Collection requested.`nAt the moment this is only fully tested with vSphere 5.5 and vSphere 6.5"
|
||||
[int]$TimeRange = "-" + $StatsRange
|
||||
}
|
||||
|
||||
$Validate = $True
|
||||
#region: Check Clusters
|
||||
Write-Verbose "$(Get-Date -Format G) Starting Cluster Validation..."
|
||||
foreach ($ClusterName in $ClusterNames) {
|
||||
$TestCluster = Get-Cluster -Name $ClusterName -ErrorAction SilentlyContinue -Verbose:$False
|
||||
if(!($TestCluster)){
|
||||
Write-Warning "No Custer found wth Name $ClusterName!"
|
||||
$Validate = $False
|
||||
}
|
||||
elseif ($TestCluster.count -gt 1) {
|
||||
Write-Warning "Multiple Custers found wth Name $ClusterName!`nUse a List of explicit Cluster Names: Recommend-Sizing -ClusterNames Cluster01, Cluster02 "
|
||||
$Validate = $False
|
||||
}
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Cluster Validation completed"
|
||||
#endregion
|
||||
}
|
||||
|
||||
Process {
|
||||
$MyView = @()
|
||||
if ($Validate -eq $True) {
|
||||
foreach ($ClusterName in $ClusterNames) {
|
||||
#region: Get Cluster Objects
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $ClusterName Cluster Objects..."
|
||||
$Cluster = Get-Cluster -Name $ClusterName -Verbose:$False
|
||||
$ClusterVMs = $Cluster | Get-VM -Verbose:$False
|
||||
$ClusterVMsPoweredOn = $ClusterVMs | where {$_.PowerState -eq "PoweredOn"}
|
||||
$ClusterDatastores = $Cluster | Get-Datastore -Verbose:$False
|
||||
$ClusterHosts = $Cluster | Get-VMHost -Verbose:$False
|
||||
$HostsAverageMemoryUsageGB = [math]::round( ($ClusterHosts | Measure-Object -Average -Property MemoryUsageGB).Average,1 )
|
||||
$HostsAverageMemoryUsage = $([math]::round( (($ClusterHosts | Measure-Object -Average -Property MemoryUsageGB).Average / ($ClusterHosts | Measure-Object -Average -Property MemoryTotalGB).Average) * 100,1 ))
|
||||
$HostsAverageCpuUsageMhz = [math]::round( ($ClusterHosts | Measure-Object -Average -Property CpuUsageMhz).Average,1 )
|
||||
$HostsAverageCpuUsage = $([math]::round( (($ClusterHosts | Measure-Object -Average -Property CpuUsageMhz).Average / ($ClusterHosts | Measure-Object -Average -Property CpuTotalMhz).Average) * 100,1 ))
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $($Cluster.name) Cluster Objects completed"
|
||||
#endregion
|
||||
|
||||
#region: CPU Calculation
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $($Cluster.name) CPU Details..."
|
||||
$VMvCPUs = ($ClusterVMs | Measure-Object -Sum -Property NumCpu).sum
|
||||
$LogicalThreads = $Cluster.ExtensionData.Summary.NumCpuThreads
|
||||
$CpuCores = $Cluster.ExtensionData.Summary.NumCpuCores
|
||||
$vCPUpCPUratio = [math]::round( $VMvCPUs / $LogicalThreads,1 )
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $($Cluster.name) CPU Details completed."
|
||||
#endregion
|
||||
|
||||
#region: Memory Calculation
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $($Cluster.name) Memory Details..."
|
||||
$AllocatedVMMemoryGB = [math]::round( ($ClusterVMs | Measure-Object -Sum -Property MemoryGB).sum )
|
||||
$PhysicalMemory = [math]::round( $Cluster.ExtensionData.Summary.TotalMemory / 1073741824,1 )
|
||||
$MemoryUsage = [math]::round( ($AllocatedVMMemoryGB / $PhysicalMemory) * 100 ,1 )
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $($Cluster.name) Memory Details completed"
|
||||
#endregion
|
||||
|
||||
if ($Stats) {
|
||||
#region: Creating VM Stats
|
||||
Write-Verbose "$(Get-Date -Format G) Create $($Cluster.name) VM Stats..."
|
||||
$VMMetrics = "disk.numberwrite.summation","disk.numberread.summation","cpu.usage.average", "mem.usage.average"
|
||||
$Start = (Get-Date).AddMinutes($TimeRange)
|
||||
$VMStats = Get-Stat -Realtime -Stat $VMMetrics -Entity $ClusterVMsPoweredOn -Start $Start -Verbose:$False
|
||||
Write-Verbose "$(Get-Date -Format G) Create $($Cluster.name) VM Stats completed"
|
||||
#endregion
|
||||
|
||||
#region: Creating VM Stats Report
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) VM Stats Report..."
|
||||
$ReportVMPerf = @()
|
||||
$ReportVMPerf = $VMStats | Group-Object -Property {$_.Entity.Name},Instance | %{
|
||||
New-Object PSObject -Property @{
|
||||
IOPSWriteAvg = ($_.Group | `
|
||||
where{$_.MetricId -eq "disk.numberwrite.summation"} | `
|
||||
Measure-Object -Property Value -Average).Average
|
||||
IOPSReadAvg = ($_.Group | `
|
||||
where{$_.MetricId -eq "disk.numberread.summation"} | `
|
||||
Measure-Object -Property Value -Average).Average
|
||||
CPUUsageAvg = ($_.Group | `
|
||||
where{$_.MetricId -eq "cpu.usage.average"} | `
|
||||
Measure-Object -Property Value -Average).Average
|
||||
MEMUsageAvg = ($_.Group | `
|
||||
where{$_.MetricId -eq "mem.usage.average"} | `
|
||||
Measure-Object -Property Value -Average).Average
|
||||
}
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) VM Stats Report completed"
|
||||
#endregion
|
||||
}
|
||||
else {
|
||||
Write-Verbose "$(Get-Date -Format G) Stats Collection skipped..."
|
||||
}
|
||||
|
||||
#region: Create VM Disk Space Report
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) VM Disk Space Report..."
|
||||
$reportDiskSpace = @()
|
||||
foreach ($ClusterVM in $ClusterVMs){
|
||||
$VMDKs = $ClusterVM | get-HardDisk -Verbose:$False
|
||||
foreach ($VMDK in $VMDKs) {
|
||||
if ($VMDK -ne $null){
|
||||
[int]$CapacityGB = $VMDK.CapacityKB/1024/1024
|
||||
$Report = [PSCustomObject] @{
|
||||
CapacityGB = $CapacityGB
|
||||
}
|
||||
$reportDiskSpace += $Report
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) VM Disk Space Report completed"
|
||||
#endregion
|
||||
|
||||
#region: Create Datastore Space Report
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) Datastore Space Report..."
|
||||
$DatastoreReport = @($ClusterDatastores | Select-Object @{N="CapacityGB";E={[math]::Round($_.CapacityGB,2)}}, @{N="FreeSpaceGB";E={[math]::Round($_.FreeSpaceGB,2)}}, @{N="UsedSpaceGB";E={[math]::Round($_.CapacityGB - $_.FreeSpaceGB,2)}})
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) Datastore Space Report completed"
|
||||
#endregion
|
||||
|
||||
#region: Create Global Report
|
||||
Write-Verbose "$(Get-Date -Format G) Process Global Report..."
|
||||
$SizingReport = [PSCustomObject] @{
|
||||
Cluster = $Cluster.name
|
||||
HAEnabled = $Cluster.HAEnabled
|
||||
DrsEnabled = $Cluster.DrsEnabled
|
||||
Hosts = $Cluster.ExtensionData.Summary.NumHosts
|
||||
HostsAverageMemoryUsageGB = $HostsAverageMemoryUsageGB
|
||||
HostsAverageMemoryUsage = "$HostsAverageMemoryUsage %"
|
||||
HostsAverageCpuUsageMhz = $HostsAverageCpuUsageMhz
|
||||
HostsAverageCpuUsage = "$HostsAverageCpuUsage %"
|
||||
PhysicalCPUCores = $CpuCores
|
||||
LogicalCPUThreads = $LogicalThreads
|
||||
VMs = $ClusterVMs.count
|
||||
ActiveVMs = $ClusterVMsPoweredOn.count
|
||||
VMvCPUs = $VMvCPUs
|
||||
vCPUpCPUratio = "$vCPUpCPUratio : 1"
|
||||
PhysicalMemoryGB = $PhysicalMemory
|
||||
AllocatedVMMemoryGB = $AllocatedVMMemoryGB
|
||||
ClusterMemoryUsage = "$MemoryUsage %"
|
||||
SumVMDiskSpaceGB = [math]::round( ($reportDiskSpace | Measure-Object -Sum -Property CapacityGB).sum, 1 )
|
||||
SumDatastoreSpaceGB = [math]::round( ($DatastoreReport | Measure-Object -Sum -Property CapacityGB).sum, 1 )
|
||||
SumDatastoreUsedSpaceGB = [math]::round( ($DatastoreReport | Measure-Object -Sum -Property UsedSpaceGB).sum, 1 )
|
||||
AverageVMIOPSWriteAvg = [math]::round( ($ReportVMPerf | Measure-Object -Average -Property IOPSWriteAvg).Average,1 )
|
||||
AverageVMIOPSReadAvg = [math]::round( ($ReportVMPerf | Measure-Object -Average -Property IOPSReadAvg).Average,1 )
|
||||
AverageVMCPUUsageAvg = "$([math]::round( ($ReportVMPerf | Measure-Object -Average -Property CPUUsageAvg).Average,1 )) %"
|
||||
AverageVMMEMUsageAvg = "$([math]::round( ($ReportVMPerf | Measure-Object -Average -Property MEMUsageAvg).Average,1 )) %"
|
||||
}
|
||||
$MyView += $SizingReport
|
||||
Write-Verbose "$(Get-Date -Format G) Process Global Report completed"
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
Else {
|
||||
Write-Error "Validation Failed! Processing Skipped"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
End {
|
||||
$MyView
|
||||
}
|
||||
|
||||
}
|
||||
111
Modules/Set-CBT/Set-CBT.psm1
Normal file
111
Modules/Set-CBT/Set-CBT.psm1
Normal file
@@ -0,0 +1,111 @@
|
||||
function Set-CBT {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.11 ver 1.0 Base Release
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
http://wahlnetwork.com/2015/12/01/change-block-tracking-cbt-powercli/
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: 5.5 U2
|
||||
PowerCLI Version: PowerCLI 6.3 R1
|
||||
PowerShell Version: 4.0
|
||||
OS Version: Windows Server 2012 R2
|
||||
===========================================================================
|
||||
Keywords vSphere, ESXi, VM, Storage, CBT, Backup
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function enables or disables CBT.
|
||||
|
||||
.Example
|
||||
Get-VN TST* | Set-CBT -DisableCBT
|
||||
|
||||
.Example
|
||||
Get-VN TST* | Set-CBT -EnableCBT
|
||||
|
||||
.PARAMETER DisableCBT
|
||||
Disables CBT for any VMs found with it enabled
|
||||
|
||||
.PARAMETER EnableCBT
|
||||
Enables CBT for any VMs found with it disabled
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0, HelpMessage = "VMs to process")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]] $myVMs,
|
||||
[Parameter(Mandatory = $False,ValueFromPipeline=$False, Position = 1, HelpMessage = "Enables CBT for any VMs found with it disabled", ParameterSetName = "EnableCBT")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[Switch]$EnableCBT,
|
||||
[Parameter(Mandatory = $False,ValueFromPipeline=$False, Position = 1, HelpMessage = "Disables CBT for any VMs found with it enabled", ParameterSetName = "DisableCBT")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[Switch]$DisableCBT
|
||||
)
|
||||
Process {
|
||||
|
||||
$vmconfigspec = New-Object -TypeName VMware.Vim.VirtualMachineConfigSpec
|
||||
Write-Verbose -Message "Walking through given VMs"
|
||||
foreach($myVM in $myVMs)
|
||||
{
|
||||
if ($DisableCBT -and $myVM.ExtensionData.Config.ChangeTrackingEnabled -eq $true -and $myVM.ExtensionData.Snapshot -eq $null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Write-Verbose -Message "Reconfiguring $($myVM.name) to disable CBT" -Verbose
|
||||
$vmconfigspec.ChangeTrackingEnabled = $false
|
||||
$myVM.ExtensionData.ReconfigVM($vmconfigspec)
|
||||
|
||||
if ($myVM.PowerState -eq "PoweredOn" ) {
|
||||
Write-Verbose -Message "Creating a snapshot on $($myVM.name) to clear CBT file" -Verbose
|
||||
$SnapShot = New-Snapshot -VM $myVM -Name "CBT Cleanup"
|
||||
|
||||
Write-Verbose -Message "Removing snapshot on $($myVM.name)" -Verbose
|
||||
$SnapShot| Remove-Snapshot -Confirm:$false
|
||||
}
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw $myVM
|
||||
}
|
||||
}
|
||||
elseif ($EnableCBT -and $myVM.ExtensionData.Config.ChangeTrackingEnabled -eq $false -and $myVM.ExtensionData.Snapshot -eq $null)
|
||||
{
|
||||
Write-Verbose -Message "Reconfiguring $($myVM.name) to enable CBT" -Verbose
|
||||
$vmconfigspec.ChangeTrackingEnabled = $true
|
||||
$myVM.ExtensionData.ReconfigVM($vmconfigspec)
|
||||
|
||||
if ($myVM.PowerState -eq "PoweredOn" ) {
|
||||
Write-Verbose -Message "Creating a snapshot on $($myVM.name) to Create CBT file" -Verbose
|
||||
$SnapShot = New-Snapshot -VM $myVM -Name "CBT Cleanup"
|
||||
|
||||
Write-Verbose -Message "Removing snapshot on $($myVM.name)" -Verbose
|
||||
$SnapShot | Remove-Snapshot -Confirm:$false
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($myVM.ExtensionData.Snapshot -ne $null -and $EnableCBT)
|
||||
{
|
||||
Write-Warning -Message "Skipping $($myVM.name) - Snapshots found"
|
||||
}
|
||||
elseif ($myVM.ExtensionData.Snapshot -ne $null -and $DisableCBT)
|
||||
{
|
||||
Write-Warning -Message "Skipping $($myVM.name) - Snapshots found"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
99
Modules/Start-UNMAP/Start-UNMAP.psm1
Normal file
99
Modules/Start-UNMAP/Start-UNMAP.psm1
Normal file
@@ -0,0 +1,99 @@
|
||||
function Start-UNMAP {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Process SCSI UNMAP on VMware Datastores
|
||||
|
||||
.DESCRIPTION
|
||||
This Function will process SCSI UNMAP on VMware Datastores via ESXCLI -V2
|
||||
|
||||
.Example
|
||||
Start-UNMAP -ClusterName myCluster -DSWildcard *RAID5*
|
||||
|
||||
.Example
|
||||
Start-UNMAP -ClusterName myCluster -DSWildcard *RAID5* -Verbose -WhatIf
|
||||
|
||||
.Notes
|
||||
NAME: Start-UNMAP.psm1
|
||||
AUTHOR: Markus Kraus
|
||||
LASTEDIT: 23.09.2016
|
||||
VERSION: 1.0
|
||||
KEYWORDS: VMware, vSphere, ESXi, SCSI, VAAI, UNMAP
|
||||
|
||||
.Link
|
||||
http://mycloudrevolution.com/
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding(SupportsShouldProcess = $true,ConfirmImpact='High')]
|
||||
param(
|
||||
[Parameter(Mandatory=$true, Position=0)]
|
||||
[String]$ClusterName,
|
||||
[Parameter(Mandatory=$true, Position=1)]
|
||||
[String]$DSWildcard
|
||||
)
|
||||
Process {
|
||||
$Validate = $true
|
||||
#region: PowerCLI Session Timeout
|
||||
Write-Verbose "Set Session Timeout ..."
|
||||
$initialTimeout = (Get-PowerCLIConfiguration -Scope Session).WebOperationTimeoutSeconds
|
||||
Set-PowerCLIConfiguration -Scope Session -WebOperationTimeoutSeconds -1 -Confirm:$False | Out-Null
|
||||
#endregion
|
||||
|
||||
#region: Get Cluster
|
||||
$Cluster = Get-Cluster -Name $ClusterName -ErrorAction SilentlyContinue
|
||||
Write-Verbose "vSphere Cluster: $Cluster"
|
||||
if (!$Cluster){Write-Error "No Cluster found!"; $Validate = $false}
|
||||
#endregion
|
||||
|
||||
#region: Get Hosts
|
||||
$ClusterHosts = $Cluster | Get-VMHost -ErrorAction SilentlyContinue | where {$_.ConnectionState -eq "Connected" -and $_.PowerState -eq "PoweredOn"}
|
||||
Write-Verbose "vSphere Cluster Hosts: $ClusterHosts"
|
||||
if (!$ClusterHosts){Write-Error "No Hosts found!"; $Validate = $false}
|
||||
#endregion
|
||||
|
||||
#region: Get Datastores
|
||||
$ClusterDataStores = $Cluster | Get-Datastore -ErrorAction SilentlyContinue | where {$_.Name -like $DSWildcard -and $_.State -eq "Available" -and $_.Accessible -eq "True"}
|
||||
Write-Verbose "vSphere Cluster Datastores: $ClusterDataStores"
|
||||
if (!$ClusterDataStores){Write-Error "No Datastores found!"; $Validate = $false}
|
||||
#endregion
|
||||
|
||||
#region: Process Datastores
|
||||
if ($Validate -eq $true) {
|
||||
Write-Verbose "Starting Loop..."
|
||||
foreach ($ClusterDataStore in $ClusterDataStores) {
|
||||
Write-Verbose "vSphere Datastore to Process: $ClusterDataStore"
|
||||
$myHost = $ClusterHosts[(Get-Random -Maximum ($ClusterHosts).count)]
|
||||
Write-Verbose "vSphere Host to Process: $myHost"
|
||||
$esxcli2 = $myHost | Get-ESXCLI -V2
|
||||
$arguments = $esxcli2.storage.vmfs.unmap.CreateArgs()
|
||||
$arguments.volumelabel = $ClusterDataStore
|
||||
$arguments.reclaimunit = "256"
|
||||
if ($PSCmdlet.ShouldProcess( $ClusterDataStore,"Starting UNMAP on $myHost")) {
|
||||
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
try {
|
||||
Write-Output "Starting UNMAP for $ClusterDataStore on $myHost..."
|
||||
$esxcli2.storage.vmfs.unmap.Invoke($arguments)
|
||||
}
|
||||
catch {
|
||||
Write-Output "A Error occured: " "" $error[0] ""
|
||||
}
|
||||
$stopwatch.Stop()
|
||||
Write-Output "UNMAP duration: $($stopwatch.Elapsed.Minutes)"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Error "Validation Failed. Processing Loop Skipped!"
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region: Revert PowerCLI Session Timeout
|
||||
Write-Verbose "Revert Session Timeout ..."
|
||||
Set-PowerCLIConfiguration -Scope Session -WebOperationTimeoutSeconds $initialTimeout -Confirm:$False | Out-Null
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
716
Modules/VAMI/VAMI.psm1
Executable file
716
Modules/VAMI/VAMI.psm1
Executable file
@@ -0,0 +1,716 @@
|
||||
Function Get-VAMISummary {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves some basic information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return basic VAMI summary info
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMISummary
|
||||
#>
|
||||
$systemVersionAPI = Get-CisService -Name 'com.vmware.appliance.system.version'
|
||||
$results = $systemVersionAPI.get() | select product, type, version, build, install_time
|
||||
|
||||
$systemUptimeAPI = Get-CisService -Name 'com.vmware.appliance.system.uptime'
|
||||
$ts = [timespan]::fromseconds($systemUptimeAPI.get().toString())
|
||||
$uptime = $ts.ToString("hh\:mm\:ss\,fff")
|
||||
|
||||
$summaryResult = [pscustomobject] @{
|
||||
Product = $results.product;
|
||||
Type = $results.type;
|
||||
Version = $results.version;
|
||||
Build = $results.build;
|
||||
InstallTime = $results.install_time;
|
||||
Uptime = $uptime
|
||||
}
|
||||
$summaryResult
|
||||
}
|
||||
|
||||
Function Get-VAMIHealth {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves health information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return VAMI health
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIHealth
|
||||
#>
|
||||
$healthOverall = (Get-CisService -Name 'com.vmware.appliance.health.system').get()
|
||||
$healthLastCheck = (Get-CisService -Name 'com.vmware.appliance.health.system').lastcheck()
|
||||
$healthCPU = (Get-CisService -Name 'com.vmware.appliance.health.load').get()
|
||||
$healthMem = (Get-CisService -Name 'com.vmware.appliance.health.mem').get()
|
||||
$healthSwap = (Get-CisService -Name 'com.vmware.appliance.health.swap').get()
|
||||
$healthStorage = (Get-CisService -Name 'com.vmware.appliance.health.storage').get()
|
||||
|
||||
# DB health only applicable for Embedded/External VCSA Node
|
||||
$vami = (Get-CisService -Name 'com.vmware.appliance.system.version').get()
|
||||
|
||||
if($vami.type -eq "vCenter Server with an embedded Platform Services Controller" -or $vami.type -eq "vCenter Server with an external Platform Services Controller") {
|
||||
$healthVCDB = (Get-CisService -Name 'com.vmware.appliance.health.databasestorage').get()
|
||||
} else {
|
||||
$healthVCDB = "N/A"
|
||||
}
|
||||
$healthSoftwareUpdates = (Get-CisService -Name 'com.vmware.appliance.health.softwarepackages').get()
|
||||
|
||||
$healthResult = [pscustomobject] @{
|
||||
HealthOverall = $healthOverall;
|
||||
HealthLastCheck = $healthLastCheck;
|
||||
HealthCPU = $healthCPU;
|
||||
HealthMem = $healthMem;
|
||||
HealthSwap = $healthSwap;
|
||||
HealthStorage = $healthStorage;
|
||||
HealthVCDB = $healthVCDB;
|
||||
HealthSoftware = $healthSoftwareUpdates
|
||||
}
|
||||
$healthResult
|
||||
}
|
||||
|
||||
Function Get-VAMIAccess {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves access information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return VAMI access interfaces (Console,DCUI,Bash Shell & SSH)
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIAccess
|
||||
#>
|
||||
$consoleAccess = (Get-CisService -Name 'com.vmware.appliance.access.consolecli').get()
|
||||
$dcuiAccess = (Get-CisService -Name 'com.vmware.appliance.access.dcui').get()
|
||||
$shellAccess = (Get-CisService -Name 'com.vmware.appliance.access.shell').get()
|
||||
$sshAccess = (Get-CisService -Name 'com.vmware.appliance.access.ssh').get()
|
||||
|
||||
$accessResult = New-Object PSObject -Property @{
|
||||
Console = $consoleAccess;
|
||||
DCUI = $dcuiAccess;
|
||||
BashShell = $shellAccess.enabled;
|
||||
SSH = $sshAccess
|
||||
}
|
||||
$accessResult
|
||||
}
|
||||
|
||||
Function Get-VAMITime {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the time and NTP info from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return current Time and NTP information
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMITime
|
||||
#>
|
||||
$systemTimeAPI = Get-CisService -Name 'com.vmware.appliance.system.time'
|
||||
$timeResults = $systemTimeAPI.get()
|
||||
|
||||
$timeSync = (Get-CisService -Name 'com.vmware.appliance.techpreview.timesync').get()
|
||||
$timeSyncMode = $timeSync.mode
|
||||
|
||||
$timeResult = [pscustomobject] @{
|
||||
Timezone = $timeResults.timezone;
|
||||
Date = $timeResults.date;
|
||||
CurrentTime = $timeResults.time;
|
||||
Mode = $timeSyncMode;
|
||||
NTPServers = "N/A";
|
||||
NTPStatus = "N/A";
|
||||
}
|
||||
|
||||
if($timeSyncMode -eq "NTP") {
|
||||
$ntpServers = (Get-CisService -Name 'com.vmware.appliance.techpreview.ntp').get()
|
||||
$timeResult.NTPServers = $ntpServers.servers
|
||||
$timeResult.NTPStatus = $ntpServers.status
|
||||
}
|
||||
$timeResult
|
||||
}
|
||||
|
||||
Function Get-VAMINetwork {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves network information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return networking information including details for each interface
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMINetwork
|
||||
#>
|
||||
$netResults = @()
|
||||
|
||||
$Hostname = (Get-CisService -Name 'com.vmware.appliance.networking.dns.hostname').get()
|
||||
$dns = (Get-CisService -Name 'com.vmware.appliance.networking.dns.servers').get()
|
||||
|
||||
Write-Host "Hostname: " $hostname
|
||||
Write-Host "DNS Servers: " $dns.servers
|
||||
|
||||
$interfaces = (Get-CisService -Name 'com.vmware.appliance.networking.interfaces').list()
|
||||
foreach ($interface in $interfaces) {
|
||||
$ipv4API = (Get-CisService -Name 'com.vmware.appliance.techpreview.networking.ipv4')
|
||||
$spec = $ipv4API.Help.get.interfaces.CreateExample()
|
||||
$spec+= $interface.name
|
||||
$ipv4result = $ipv4API.get($spec)
|
||||
|
||||
$interfaceResult = [pscustomobject] @{
|
||||
Inteface = $interface.name;
|
||||
MAC = $interface.mac;
|
||||
Status = $interface.status;
|
||||
Mode = $ipv4result.mode;
|
||||
IP = $ipv4result.address;
|
||||
Prefix = $ipv4result.prefix;
|
||||
Gateway = $ipv4result.default_gateway;
|
||||
Updateable = $ipv4result.updateable
|
||||
}
|
||||
$netResults += $interfaceResult
|
||||
}
|
||||
$netResults
|
||||
}
|
||||
|
||||
Function Get-VAMIDisks {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves VMDK disk number to partition mapping VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return VMDK disk number to OS partition mapping
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIDisks
|
||||
#>
|
||||
$storageAPI = Get-CisService -Name 'com.vmware.appliance.system.storage'
|
||||
$disks = $storageAPI.list()
|
||||
|
||||
foreach ($disk in $disks | sort {[int]$_.disk.toString()}) {
|
||||
$disk | Select Disk, Partition
|
||||
}
|
||||
}
|
||||
|
||||
Function Start-VAMIDiskResize {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function triggers an OS partition resize after adding additional disk capacity
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function triggers OS partition resize operation
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Start-VAMIDiskResize
|
||||
#>
|
||||
$storageAPI = Get-CisService -Name 'com.vmware.appliance.system.storage'
|
||||
Write-Host "Initiated OS partition resize operation ..."
|
||||
$storageAPI.resize()
|
||||
}
|
||||
|
||||
Function Get-VAMIStatsList {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list avialable monitoring metrics in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of available monitoring metrics that can be queried
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIStatsList
|
||||
#>
|
||||
$monitoringAPI = Get-CisService -Name 'com.vmware.appliance.monitoring'
|
||||
$ids = $monitoringAPI.list() | Select id | Sort-Object -Property id
|
||||
|
||||
foreach ($id in $ids) {
|
||||
$id
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-VAMIStorageUsed {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the individaul OS partition storage utilization
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return individual OS partition storage utilization
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIStorageUsed
|
||||
#>
|
||||
$monitoringAPI = Get-CisService 'com.vmware.appliance.monitoring'
|
||||
$querySpec = $monitoringAPI.help.query.item.CreateExample()
|
||||
|
||||
# List of IDs from Get-VAMIStatsList to query
|
||||
$querySpec.Names = @(
|
||||
"storage.used.filesystem.autodeploy",
|
||||
"storage.used.filesystem.boot",
|
||||
"storage.used.filesystem.coredump",
|
||||
"storage.used.filesystem.imagebuilder",
|
||||
"storage.used.filesystem.invsvc",
|
||||
"storage.used.filesystem.log",
|
||||
"storage.used.filesystem.netdump",
|
||||
"storage.used.filesystem.root",
|
||||
"storage.used.filesystem.updatemgr",
|
||||
"storage.used.filesystem.vcdb_core_inventory",
|
||||
"storage.used.filesystem.vcdb_seat",
|
||||
"storage.used.filesystem.vcdb_transaction_log",
|
||||
"storage.totalsize.filesystem.autodeploy",
|
||||
"storage.totalsize.filesystem.boot",
|
||||
"storage.totalsize.filesystem.coredump",
|
||||
"storage.totalsize.filesystem.imagebuilder",
|
||||
"storage.totalsize.filesystem.invsvc",
|
||||
"storage.totalsize.filesystem.log",
|
||||
"storage.totalsize.filesystem.netdump",
|
||||
"storage.totalsize.filesystem.root",
|
||||
"storage.totalsize.filesystem.updatemgr",
|
||||
"storage.totalsize.filesystem.vcdb_core_inventory",
|
||||
"storage.totalsize.filesystem.vcdb_seat",
|
||||
"storage.totalsize.filesystem.vcdb_transaction_log"
|
||||
)
|
||||
|
||||
# Tuple (Filesystem Name, Used, Total) to store results
|
||||
$storageStats = @{
|
||||
"autodeploy"=@{"name"="/storage/autodeploy";"used"=0;"total"=0};
|
||||
"boot"=@{"name"="/boot";"used"=0;"total"=0};
|
||||
"coredump"=@{"name"="/storage/core";"used"=0;"total"=0};
|
||||
"imagebuilder"=@{"name"="/storage/imagebuilder";"used"=0;"total"=0};
|
||||
"invsvc"=@{"name"="/storage/invsvc";"used"=0;"total"=0};
|
||||
"log"=@{"name"="/storage/log";"used"=0;"total"=0};
|
||||
"netdump"=@{"name"="/storage/netdump";"used"=0;"total"=0};
|
||||
"root"=@{"name"="/";"used"=0;"total"=0};
|
||||
"updatemgr"=@{"name"="/storage/updatemgr";"used"=0;"total"=0};
|
||||
"vcdb_core_inventory"=@{"name"="/storage/db";"used"=0;"total"=0};
|
||||
"vcdb_seat"=@{"name"="/storage/seat";"used"=0;"total"=0};
|
||||
"vcdb_transaction_log"=@{"name"="/storage/dblog";"used"=0;"total"=0}
|
||||
}
|
||||
|
||||
$querySpec.interval = "DAY1"
|
||||
$querySpec.function = "MAX"
|
||||
$querySpec.start_time = ((get-date).AddDays(-1))
|
||||
$querySpec.end_time = (Get-Date)
|
||||
$queryResults = $monitoringAPI.query($querySpec) | Select * -ExcludeProperty Help
|
||||
|
||||
foreach ($queryResult in $queryResults) {
|
||||
# Update hash if its used storage results
|
||||
if($queryResult.name -match "used") {
|
||||
$key = (($queryResult.name).toString()).split(".")[-1]
|
||||
$value = [Math]::Round([int]($queryResult.data[1]).toString()/1MB,2)
|
||||
$storageStats[$key]["used"] = $value
|
||||
# Update hash if its total storage results
|
||||
} else {
|
||||
$key = (($queryResult.name).toString()).split(".")[-1]
|
||||
$value = [Math]::Round([int]($queryResult.data[1]).toString()/1MB,2)
|
||||
$storageStats[$key]["total"] = $value
|
||||
}
|
||||
}
|
||||
|
||||
$storageResults = @()
|
||||
foreach ($key in $storageStats.keys | Sort-Object -Property name) {
|
||||
$statResult = [pscustomobject] @{
|
||||
Filesystem = $storageStats[$key].name;
|
||||
Used = $storageStats[$key].used;
|
||||
Total = $storageStats[$key].total
|
||||
}
|
||||
$storageResults += $statResult
|
||||
}
|
||||
$storageResults
|
||||
}
|
||||
|
||||
Function Get-VAMIService {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list of services in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of services and their description
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIService
|
||||
.EXAMPLE
|
||||
Get-VAMIService -Name rbd
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$false,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
if($Name -ne "") {
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
|
||||
try {
|
||||
$serviceStatus = $vMonAPI.get($name,0)
|
||||
$serviceString = [pscustomobject] @{
|
||||
Name = $name;
|
||||
State = $serviceStatus.state;
|
||||
Health = "";
|
||||
Startup = $serviceStatus.startup_type
|
||||
}
|
||||
if($serviceStatus.health -eq $null) { $serviceString.Health = "N/A"} else { $serviceString.Health = $serviceStatus.health }
|
||||
$serviceString
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
} else {
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
$services = $vMonAPI.list_details()
|
||||
|
||||
$serviceResult = @()
|
||||
foreach ($key in $services.keys | Sort-Object -Property Value) {
|
||||
$serviceString = [pscustomobject] @{
|
||||
Name = $key;
|
||||
State = $services[$key].state;
|
||||
Health = "N/A";
|
||||
Startup = $services[$key].Startup_type
|
||||
}
|
||||
if($services[$key].health -eq $null) { $serviceString.Health = "N/A"} else { $serviceString.Health = $services[$key].health }
|
||||
|
||||
$serviceResult += $serviceString
|
||||
}
|
||||
$serviceResult
|
||||
}
|
||||
}
|
||||
|
||||
Function Start-VAMIService {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list of services in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of services and their description
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Start-VAMIService -Name rbd
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
|
||||
try {
|
||||
Write-Host "Starting $name service ..."
|
||||
$vMonAPI.start($name)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
|
||||
Function Stop-VAMIService {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list of services in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of services and their description
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Stop-VAMIService -Name rbd
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
|
||||
try {
|
||||
Write-Host "Stopping $name service ..."
|
||||
$vMonAPI.stop($name)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-VAMIBackupSize {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the backup size of the VCSA from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return the current backup size of the VCSA (common and core data)
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIBackupSize
|
||||
#>
|
||||
$recoveryAPI = Get-CisService 'com.vmware.appliance.recovery.backup.parts'
|
||||
$backupParts = $recoveryAPI.list() | select id
|
||||
|
||||
$estimateBackupSize = 0
|
||||
$backupPartSizes = ""
|
||||
foreach ($backupPart in $backupParts) {
|
||||
$partId = $backupPart.id.value
|
||||
$partSize = $recoveryAPI.get($partId)
|
||||
$estimateBackupSize += $partSize
|
||||
$backupPartSizes += $partId + " data is " + $partSize + " MB`n"
|
||||
}
|
||||
|
||||
Write-Host "Estimated Backup Size: $estimateBackupSize MB"
|
||||
Write-Host $backupPartSizes
|
||||
}
|
||||
|
||||
Function Get-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves VAMI local users using VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to retrieve VAMI local users
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIUser
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$false,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
$userAPI = Get-CisService 'com.vmware.appliance.techpreview.localaccounts.user'
|
||||
|
||||
$userResults = @()
|
||||
|
||||
if($Name -ne "") {
|
||||
try {
|
||||
$user = $userAPI.get($name)
|
||||
|
||||
$userString = [pscustomobject] @{
|
||||
User = $user.username
|
||||
Name = $user.fullname
|
||||
Email = $user.email
|
||||
Status = $user.status
|
||||
PasswordStatus = $user.passwordstatus
|
||||
Role = $user.role
|
||||
}
|
||||
$userResults += $userString
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
} else {
|
||||
$users = $userAPI.list()
|
||||
|
||||
foreach ($user in $users) {
|
||||
$userString = [pscustomobject] @{
|
||||
User = $user.username
|
||||
Name = $user.fullname
|
||||
Email = $user.email
|
||||
Status = $user.status
|
||||
PasswordStatus = $user.passwordstatus
|
||||
Role = $user.role
|
||||
}
|
||||
$userResults += $userString
|
||||
}
|
||||
}
|
||||
$userResults
|
||||
}
|
||||
|
||||
Function New-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function to create new VAMI local user using VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to create a new VAMI local user
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
New-VAMIUser -name lamw -fullname "William Lam" -role "operator" -email "lamw@virtuallyghetto.com" -password "VMware1!"
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$name,
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$fullname,
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[ValidateSet("admin","operator","superAdmin")][String]$role,
|
||||
[Parameter(
|
||||
Mandatory=$false)
|
||||
]
|
||||
[String]$email="",
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$password
|
||||
)
|
||||
|
||||
$userAPI = Get-CisService 'com.vmware.appliance.techpreview.localaccounts.user'
|
||||
$createSpec = $userAPI.Help.add.config.CreateExample()
|
||||
|
||||
$createSpec.username = $name
|
||||
$createSpec.fullname = $fullname
|
||||
$createSpec.role = $role
|
||||
$createSpec.email = $email
|
||||
$createSpec.password = [VMware.VimAutomation.Cis.Core.Types.V1.Secret]$password
|
||||
|
||||
try {
|
||||
Write-Host "Creating new user $name ..."
|
||||
$userAPI.add($createSpec)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
|
||||
Function Remove-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function to remove VAMI local user using VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to remove VAMI local user
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIAccess
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$name,
|
||||
[Parameter(
|
||||
Mandatory=$false)
|
||||
]
|
||||
[boolean]$confirm=$false
|
||||
)
|
||||
|
||||
if(!$confirm) {
|
||||
$answer = Read-Host -Prompt "Do you want to delete user $name (Y or N)"
|
||||
if($answer -eq "Y" -or $answer -eq "y") {
|
||||
$userAPI = Get-CisService 'com.vmware.appliance.techpreview.localaccounts.user'
|
||||
|
||||
try {
|
||||
Write-Host "Deleting user $name ..."
|
||||
$userAPI.delete($name)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
413
Modules/VCHA/VCHA.psm1
Normal file
413
Modules/VCHA/VCHA.psm1
Normal file
@@ -0,0 +1,413 @@
|
||||
Function Get-VCHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the VCHA Configuration which provides you with
|
||||
the current state, mode as well as the IP Addresses of the Active,
|
||||
Passive & Witness Node. This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to return VCHA Configuration
|
||||
.EXAMPLE
|
||||
Get-VCHAConfig
|
||||
#>
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$vcHAConfig = $vcHAClusterConfig.getVchaConfig()
|
||||
|
||||
$vcHAState = $vcHAConfig.State
|
||||
switch($vcHAState) {
|
||||
configured {
|
||||
$activeIp = $vcHAConfig.FailoverNodeInfo1.ClusterIpSettings.Ip.IpAddress
|
||||
$passiveIp = $vcHAConfig.FailoverNodeInfo2.ClusterIpSettings.Ip.IpAddress
|
||||
$witnessIp = $vcHAConfig.WitnessNodeInfo.IpSettings.Ip.IpAddress
|
||||
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
$vcHAMode = $vcHAClusterManager.getClusterMode()
|
||||
|
||||
Write-Host ""
|
||||
Write-Host -NoNewline -ForegroundColor Green "VCHA State: "
|
||||
Write-Host -ForegroundColor White "$vcHAState"
|
||||
Write-Host -NoNewline -ForegroundColor Green " VCHA Mode: "
|
||||
Write-Host -ForegroundColor White "$vcHAMode"
|
||||
Write-Host -NoNewline -ForegroundColor Green " ActiveIP: "
|
||||
Write-Host -ForegroundColor White "$activeIp"
|
||||
Write-Host -NoNewline -ForegroundColor Green " PassiveIP: "
|
||||
Write-Host -ForegroundColor White "$passiveIp"
|
||||
Write-Host -NoNewline -ForegroundColor Green " WitnessIP: "
|
||||
Write-Host -ForegroundColor White "$witnessIp`n"
|
||||
;break
|
||||
}
|
||||
invalid { Write-Host -ForegroundColor Red "VCHA State is in invalid state ...";break}
|
||||
notConfigured { Write-Host "VCHA is not configured";break}
|
||||
prepared { Write-Host "VCHA is being prepared, please try again in a little bit ...";break}
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-VCHAClusterHealth {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the VCHA Cluster Health which provides more info
|
||||
on each of the individual. This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to return VCHA Cluster Health
|
||||
.EXAMPLE
|
||||
Get-VCHAClusterHealth
|
||||
#>
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$vcHAConfig = $vcHAClusterConfig.getVchaConfig()
|
||||
$vcHAState = $vcHAConfig.State
|
||||
|
||||
switch($vcHAState) {
|
||||
invalid { Write-Host -ForegroundColor Red "VCHA State is in invalid state ...";break}
|
||||
notConfigured { Write-Host "VCHA is not configured";break}
|
||||
prepared { Write-Host "VCHA is being prepared ...";break}
|
||||
configured {
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
$healthInfo = $vcHAClusterManager.GetVchaClusterHealth()
|
||||
|
||||
$vcClusterState = $healthInfo.RuntimeInfo.ClusterState
|
||||
$nodeState = $healthInfo.RuntimeInfo.NodeInfo
|
||||
|
||||
Write-Host ""
|
||||
Write-Host -NoNewline -ForegroundColor Green "VCHA Cluster State: "
|
||||
Write-Host -ForegroundColor White "$vcClusterState"
|
||||
Write-Host -NoNewline -ForegroundColor Green "VCHA Node Information: "
|
||||
$nodeState | Select NodeIp, NodeRole, NodeState
|
||||
;break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Set-VCHAClusterMode {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function allows you to set the mode of the VCHA Cluster whether
|
||||
that is Enabled, Disabled or in Maintenance Mode. This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to set VCHA Cluster Mode
|
||||
.EXAMPLE
|
||||
Set-VCHAClusterMode -Enabled $true
|
||||
.EXAMPLE
|
||||
Set-VCHAClusterMode -Disabled $true
|
||||
.EXAMPLE
|
||||
Set-VCHAClusterMode -Maintenance $true
|
||||
#>
|
||||
param(
|
||||
[Switch]$Enabled,
|
||||
[Switch]$Disabled,
|
||||
[Switch]$Maintenance
|
||||
)
|
||||
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
|
||||
if($Enabled) {
|
||||
Write-Host "Setting VCHA Cluster to Enabled ..."
|
||||
$task = $vcHAClusterManager.setClusterMode_Task("enabled")
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
} elseIf($Maintenance) {
|
||||
Write-Host "Setting VCHA Cluster to Maintenance ..."
|
||||
$task = $vcHAClusterManager.setClusterMode_Task("maintenance")
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
} elseIf($Disabled) {
|
||||
Write-Host "`nSetting VCHA Cluster to Disabled ...`n"
|
||||
$task = $vcHAClusterManager.setClusterMode_Task("disabled")
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
}
|
||||
}
|
||||
|
||||
Function New-VCHABasicConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function allows you create a new "Basic" VCHA Cluster, it does not
|
||||
cover the "Advanced" use case. You will need to ensure that you have a
|
||||
"Self Managed" vCenter Server before attempting this workflow.
|
||||
This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to create "Basic" VCHA Cluster
|
||||
.PARAMETER VCSAVM
|
||||
The name of the vCenter Server Appliance (VCSA) in which you wish to enable VCHA on (must be self-managed)
|
||||
.PARAMETER HANetwork
|
||||
The name of the Virtual Portgroup or Distributed Portgroup used for the HA Network
|
||||
.PARAMETER ActiveHAIp
|
||||
The IP Address for the Active VCSA node
|
||||
.PARAMETER ActiveNetmask
|
||||
The Netmask for the Active VCSA node
|
||||
.PARAMETER PassiveHAIp
|
||||
The IP Address for the Passive VCSA node
|
||||
.PARAMETER PassiveNetmask
|
||||
The Netmask for the Passive VCSA node
|
||||
.PARAMETER WitnessHAIp
|
||||
The IP Address for the Witness VCSA node
|
||||
.PARAMETER WitnessNetmask
|
||||
The Netmask for the Witness VCSA node
|
||||
.PARAMETER PassiveDatastore
|
||||
The name of the datastore to deploy the Passive node to
|
||||
.PARAMETER WitnessDatastore
|
||||
The name of the datastore to deploy the Witness node to
|
||||
.PARAMETER VCUsername
|
||||
The VCSA username (e.g. administrator@vghetto.local)
|
||||
.PARAMETER VCPassword
|
||||
The VCSA password
|
||||
.EXAMPLE
|
||||
New-VCHABasicConfig -VCSAVM "vcenter65-1" -HANetwork "DVPG-VCHA-Network" `
|
||||
-ActiveHAIp 192.168.1.70 `
|
||||
-ActiveNetmask 255.255.255.0 `
|
||||
-PassiveHAIp 192.168.1.71 `
|
||||
-PassiveNetmask 255.255.255.0 `
|
||||
-WitnessHAIp 192.168.1.72 `
|
||||
-WitnessNetmask 255.255.255.0 `
|
||||
-PassiveDatastore "vsanDatastore" `
|
||||
-WitnessDatastore "vsanDatastore" `
|
||||
-VCUsername "administrator@vghetto.local" `
|
||||
-VCPassword "VMware1!"
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$VCSAVM,
|
||||
[String]$HANetwork,
|
||||
[String]$ActiveHAIp,
|
||||
[String]$ActiveNetmask,
|
||||
[String]$PassiveHAIp,
|
||||
[String]$PassiveNetmask,
|
||||
[String]$PassiveDatastore,
|
||||
[String]$WitnessHAIp,
|
||||
[String]$WitnessNetmask,
|
||||
[String]$WitnessDatastore,
|
||||
# Crappy Implementation but need to research more into using PSH Credential
|
||||
[String]$VCUsername,
|
||||
[String]$VCPassword
|
||||
)
|
||||
|
||||
$VCSAVMView = Get-View -ViewType VirtualMachine -Filter @{"name"=$VCSAVM}
|
||||
if($VCSAVMView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Virtual Machine $VCSAVM"
|
||||
return
|
||||
}
|
||||
|
||||
$HANetworkView = Get-View -ViewType Network -Filter @{"name"=$HANetwork}
|
||||
if($HANetworkView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Network $HANetwork"
|
||||
return
|
||||
}
|
||||
|
||||
$PassiveDatastoreView = Get-View -ViewType Datastore -Filter @{"name"=$PassiveDatastore}
|
||||
if($PassiveDatastoreView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Passive Datastore $PassiveDatastore"
|
||||
return
|
||||
}
|
||||
|
||||
$WitnessDatastoreView = Get-View -ViewType Datastore -Filter @{"name"=$WitnessDatastore}
|
||||
if($WitnessDatastoreView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Witness Datastore $WitnessDatastore"
|
||||
return
|
||||
}
|
||||
|
||||
$vcIP = $VCSAVMView.Guest.IpAddress
|
||||
if($vcIP -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to automatically retrieve the IP Address of $VCSAVM which is needed to use this function"
|
||||
return
|
||||
}
|
||||
|
||||
# Retrieve Source VC SSL Thumbprint
|
||||
$vcurl = "https://$vcIP"
|
||||
add-type @"
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
public class IDontCarePolicy : ICertificatePolicy {
|
||||
public IDontCarePolicy() {}
|
||||
public bool CheckValidationResult(
|
||||
ServicePoint sPoint, X509Certificate cert,
|
||||
WebRequest wRequest, int certProb) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
"@
|
||||
[System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy
|
||||
# Need to do simple GET connection for this method to work
|
||||
Invoke-RestMethod -Uri $VCURL -Method Get | Out-Null
|
||||
|
||||
$endpoint_request = [System.Net.Webrequest]::Create("$vcurl")
|
||||
# Get Thumbprint + add colons for a valid Thumbprint
|
||||
$vcSSLThumbprint = ($endpoint_request.ServicePoint.Certificate.GetCertHashString()) -replace '(..(?!$))','$1:'
|
||||
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$spec = New-Object VMware.Vim.VchaClusterDeploymentSpec
|
||||
|
||||
$activeNetworkConfig = New-Object VMware.Vim.ClusterNetworkConfigSpec
|
||||
$activeNetworkConfig.NetworkPortGroup = $HANetworkView.MoRef
|
||||
$ipSettings = New-Object Vmware.Vim.CustomizationIPSettings
|
||||
$ipSettings.SubnetMask = $ActiveNetmask
|
||||
$activeIpSpec = New-Object VMware.Vim.CustomizationFixedIp
|
||||
$activeIpSpec.IpAddress = $ActiveHAIp
|
||||
$ipSettings.Ip = $activeIpSpec
|
||||
$activeNetworkConfig.IpSettings = $ipSettings
|
||||
$spec.ActiveVcNetworkConfig = $activeNetworkConfig
|
||||
|
||||
$activeVCConfig = New-Object Vmware.Vim.SourceNodeSpec
|
||||
$activeVCConfig.ActiveVc = $VCSAVMView.MoRef
|
||||
$serviceLocator = New-Object Vmware.Vim.ServiceLocator
|
||||
$credential = New-Object VMware.Vim.ServiceLocatorNamePassword
|
||||
$credential.username = $VCUsername
|
||||
$credential.password = $VCPassword
|
||||
$serviceLocator.Credential = $credential
|
||||
$serviceLocator.InstanceUuid = $global:DefaultVIServer.InstanceUuid
|
||||
$serviceLocator.Url = $vcurl
|
||||
$serviceLocator.SslThumbprint = $vcSSLThumbprint
|
||||
$activeVCConfig.ManagementVc = $serviceLocator
|
||||
$spec.ActiveVcSpec = $activeVCConfig
|
||||
|
||||
$passiveSpec = New-Object VMware.Vim.PassiveNodeDeploymentSpec
|
||||
$passiveSpec.Folder = (Get-View (Get-Folder vm)).MoRef
|
||||
$passiveIpSettings = New-object Vmware.Vim.CustomizationIPSettings
|
||||
$passiveIpSettings.SubnetMask = $passiveNetmask
|
||||
$passiveIpSpec = New-Object VMware.Vim.CustomizationFixedIp
|
||||
$passiveIpSpec.IpAddress = $passiveHAIp
|
||||
$passiveIpSettings.Ip = $passiveIpSpec
|
||||
$passiveSpec.IpSettings = $passiveIpSettings
|
||||
$passiveSpec.NodeName = $VCSAVMView.Name + "-Passive"
|
||||
$passiveSpec.datastore = $PassiveDatastoreView.MoRef
|
||||
$spec.PassiveDeploymentSpec = $passiveSpec
|
||||
|
||||
$witnessSpec = New-Object VMware.Vim.NodeDeploymentSpec
|
||||
$witnessSpec.Folder = (Get-View (Get-Folder vm)).MoRef
|
||||
$witnessSpec.NodeName = $VCSAVMView.Name + "-Witness"
|
||||
$witnessIpSettings = New-object Vmware.Vim.CustomizationIPSettings
|
||||
$witnessIpSettings.SubnetMask = $witnessNetmask
|
||||
$witnessIpSpec = New-Object VMware.Vim.CustomizationFixedIp
|
||||
$witnessIpSpec.IpAddress = $witnessHAIp
|
||||
$witnessIpSettings.Ip = $witnessIpSpec
|
||||
$witnessSpec.IpSettings = $witnessIpSettings
|
||||
$witnessSpec.datastore = $WitnessDatastoreView.MoRef
|
||||
$spec.WitnessDeploymentSpec = $witnessSpec
|
||||
|
||||
Write-Host "`nDeploying VCHA Cluster ...`n"
|
||||
$task = $vcHAClusterConfig.deployVcha_Task($spec)
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task -Verbose
|
||||
}
|
||||
|
||||
Function Remove-VCHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function allows you destroy a VCHA Cluster. In addition, you have
|
||||
the option to specify whether you would like both the Passive & Witness
|
||||
Virtual Machines be deleted after the VCHA Cluster has been destroyed.
|
||||
This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to destroy a VCHA Cluster Mode
|
||||
.EXAMPLE
|
||||
Remove-VCHAConfig
|
||||
.EXAMPLE
|
||||
Remove-VCHAConfig -Confirm:$false
|
||||
.EXAMPLE
|
||||
Remove-VCHAConfig -DeleteVM $true -Confirm:$false
|
||||
.NOTES
|
||||
Before you can destroy a VCHA Cluster, you must make sure it is first
|
||||
disabled. Run the Set-VCHAClusterMode -Disabled $true to do so
|
||||
#>
|
||||
param(
|
||||
[Boolean]$Confirm=$true,
|
||||
[Switch]$DeleteVM=$false
|
||||
)
|
||||
|
||||
$Verified = $false
|
||||
if($Confirm -eq $true) {
|
||||
Write-Host -ForegroundColor Yellow "`nDo you want to destroy VCHA Cluster?"
|
||||
$answer = Read-Host -Prompt "Do you accept (Y or N)"
|
||||
if($answer -eq "Y" -or $answer -eq "y") {
|
||||
$Verified = $true
|
||||
}
|
||||
} else {
|
||||
$Verified = $true
|
||||
}
|
||||
|
||||
if($Verified) {
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
$vcHAMode = $vcHAClusterManager.getClusterMode()
|
||||
|
||||
if($vcHAMode -ne "disabled") {
|
||||
Write-Host -ForegroundColor Yellow "To destroy VCHA Cluster, you must first set the VCHA Cluster Mode to `"Disabled`""
|
||||
Exit
|
||||
}
|
||||
|
||||
# Query BIOS UUID of the Passive/Witness to be able to delete
|
||||
if($DeleteVM) {
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$vcHAConfig = $vcHAClusterConfig.getVchaConfig()
|
||||
$passiveBiosUUID = $vcHAConfig.FailoverNodeInfo2.biosUuid
|
||||
$witnessBiosUUID = $vcHAConfig.WitnessNodeInfo.biosUuid
|
||||
}
|
||||
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
|
||||
Write-Host "Destroying VCHA Cluster ..."
|
||||
$task = $vcHAClusterConfig.destroyVcha_Task()
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
|
||||
# After VCHA Cluster has been destroyed, we can now delete the VMs we had queried earlier
|
||||
if($DeleteVM) {
|
||||
if($passiveBiosUUID -ne $null -and $witnessBiosUUID -ne $null) {
|
||||
$searchIndex = Get-View searchIndex
|
||||
|
||||
$passiveVM = $searchIndex.FindByUuid($null,$passiveBiosUUID,$true,$null)
|
||||
$witnessVM = $searchIndex.FindByUuid($null,$witnessBiosUUID,$true,$null)
|
||||
|
||||
if($passiveVM -ne $null -and $witnessVM -ne $null) {
|
||||
Write-Host "Powering off & deleting Passive VM ..."
|
||||
Stop-VM -VM (Get-View $passiveVM).Name -Confirm:$false | Out-Null
|
||||
Remove-VM (Get-View $passiveVM).Name -DeletePermanently -Confirm:$false
|
||||
Write-Host "Powering off & deleting Witness VM ..."
|
||||
Stop-VM -VM (Get-View $witnessVM).Name -Confirm:$false | Out-Null
|
||||
Remove-VM (Get-View $witnessVM).Name -DeletePermanently -Confirm:$false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
function Get-VMCPSettings {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 10/27/2015 9:25 PM
|
||||
Created by: Brian Graf
|
||||
Twitter: @vBrianGraf
|
||||
VMware Blog: blogs.vmware.com/powercli
|
||||
Personal Blog: www.vtagion.com
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function will allow users to view the VMCP settings for their clusters
|
||||
|
||||
.Example
|
||||
# This will show you the VMCP settings of your cluster
|
||||
Get-VMCPSettings -cluster LAB-CL
|
||||
|
||||
.Example
|
||||
# This will show you the VMCP settings of your cluster
|
||||
Get-VMCPSettings -cluster (Get-Cluster Lab-CL)
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$True,
|
||||
ValueFromPipelineByPropertyName=$True,
|
||||
HelpMessage='What is the Cluster Name?')]
|
||||
$cluster
|
||||
)
|
||||
Begin {
|
||||
# Determine input and convert to ClusterImpl object
|
||||
Switch ($cluster.GetType().Name)
|
||||
{
|
||||
"string" {$CL = Get-Cluster $cluster}
|
||||
"ClusterImpl" {$CL = $cluster}
|
||||
}
|
||||
}
|
||||
Process {
|
||||
# Work with the Cluster View
|
||||
$ClusterMod = Get-View -Id "ClusterComputeResource-$($cl.ExtensionData.MoRef.Value)"
|
||||
|
||||
# Create Hashtable with desired properties to return
|
||||
$properties = [ordered]@{
|
||||
'Cluster' = $ClusterMod.Name;
|
||||
'VMCP Status' = $clustermod.Configuration.DasConfig.VmComponentProtecting;
|
||||
'Protection For APD' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForAPD;
|
||||
'APD Timeout Enabled' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.EnableAPDTimeoutForHosts;
|
||||
'APD Timeout (Seconds)' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmTerminateDelayForAPDSec;
|
||||
'Reaction on APD Cleared' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmReactionOnAPDCleared;
|
||||
'Protection For PDL' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForPDL
|
||||
}
|
||||
|
||||
# Create PSObject with the Hashtable
|
||||
$object = New-Object -TypeName PSObject -Prop $properties
|
||||
|
||||
# Show object
|
||||
return $object
|
||||
}
|
||||
End {}
|
||||
|
||||
}
|
||||
|
||||
function Set-VMCPSettings {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 10/27/2015 9:25 PM
|
||||
Created by: Brian Graf
|
||||
Twitter: @vBrianGraf
|
||||
VMware Blog: blogs.vmware.com/powercli
|
||||
Personal Blog: www.vtagion.com
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function will allow users to enable/disable VMCP and also allow
|
||||
them to configure the additional VMCP settings
|
||||
For each parameter, users should use the 'Tab' button to auto-fill the
|
||||
possible values.
|
||||
|
||||
.Example
|
||||
# This will enable VMCP and configure the Settings
|
||||
Set-VMCPSettings -cluster LAB-CL -enableVMCP:$True -VmStorageProtectionForPDL `
|
||||
restartAggressive -VmStorageProtectionForAPD restartAggressive `
|
||||
-VmTerminateDelayForAPDSec 2000 -VmReactionOnAPDCleared reset
|
||||
|
||||
.Example
|
||||
# This will disable VMCP and configure the Settings
|
||||
Set-VMCPSettings -cluster LAB-CL -enableVMCP:$False -VmStorageProtectionForPDL `
|
||||
disabled -VmStorageProtectionForAPD disabled `
|
||||
-VmTerminateDelayForAPDSec 600 -VmReactionOnAPDCleared none
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$True,
|
||||
ValueFromPipelineByPropertyName=$True,
|
||||
HelpMessage='What is the Cluster Name?')]
|
||||
$cluster,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='True=Enabled False=Disabled')]
|
||||
[switch]$enableVMCP,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Actions that can be taken in response to a PDL event')]
|
||||
[ValidateSet("disabled","warning","restartAggressive")]
|
||||
[string]$VmStorageProtectionForPDL,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Options available for an APD response')]
|
||||
[ValidateSet("disabled","restartConservative","restartAggressive","warning")]
|
||||
[string]$VmStorageProtectionForAPD,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Value in seconds')]
|
||||
[Int]$VmTerminateDelayForAPDSec,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='This setting will instruct vSphere HA to take a certain action if an APD event is cleared')]
|
||||
[ValidateSet("reset","none")]
|
||||
[string]$VmReactionOnAPDCleared
|
||||
|
||||
)
|
||||
Begin{
|
||||
|
||||
# Determine input and convert to ClusterImpl object
|
||||
Switch ($cluster.GetType().Name)
|
||||
{
|
||||
"string" {$CL = Get-Cluster $cluster}
|
||||
"ClusterImpl" {$CL = $cluster}
|
||||
}
|
||||
}
|
||||
Process{
|
||||
# Create the object we will configure
|
||||
$settings = New-Object VMware.Vim.ClusterConfigSpecEx
|
||||
$settings.dasConfig = New-Object VMware.Vim.ClusterDasConfigInfo
|
||||
|
||||
# Based on $enableVMCP switch
|
||||
if ($enableVMCP -eq $false) {
|
||||
$settings.dasConfig.vmComponentProtecting = "disabled"
|
||||
}
|
||||
elseif ($enableVMCP -eq $true) {
|
||||
$settings.dasConfig.vmComponentProtecting = "enabled"
|
||||
}
|
||||
|
||||
#Create the VMCP object to work with
|
||||
$settings.dasConfig.defaultVmSettings = New-Object VMware.Vim.ClusterDasVmSettings
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings = New-Object VMware.Vim.ClusterVmComponentProtectionSettings
|
||||
|
||||
#Storage Protection For PDL
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForPDL = "$VmStorageProtectionForPDL"
|
||||
|
||||
#Storage Protection for APD
|
||||
switch ($VmStorageProtectionForAPD) {
|
||||
"disabled" {
|
||||
# If Disabled, there is no need to set the Timeout Value
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'disabled'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $false
|
||||
}
|
||||
|
||||
"restartConservative" {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'restartConservative'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $true
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmTerminateDelayForAPDSec = $VmTerminateDelayForAPDSec
|
||||
}
|
||||
|
||||
"restartAggressive" {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'restartAggressive'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $true
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmTerminateDelayForAPDSec = $VmTerminateDelayForAPDSec
|
||||
}
|
||||
|
||||
"warning" {
|
||||
# If Warning, there is no need to set the Timeout Value
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'warning'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Reaction On APD Cleared
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmReactionOnAPDCleared = "$VmReactionOnAPDCleared"
|
||||
|
||||
# Execute API Call
|
||||
$modify = $true
|
||||
$ClusterMod = Get-View -Id "ClusterComputeResource-$($cl.ExtensionData.MoRef.Value)"
|
||||
$ClusterMod.ReconfigureComputeResource_Task($settings, $modify) | out-null
|
||||
|
||||
|
||||
|
||||
}
|
||||
End{
|
||||
# Update variable data after API call
|
||||
$ClusterMod.updateViewData()
|
||||
|
||||
# Create Hashtable with desired properties to return
|
||||
$properties = [ordered]@{
|
||||
'Cluster' = $ClusterMod.Name;
|
||||
'VMCP Status' = $clustermod.Configuration.DasConfig.VmComponentProtecting;
|
||||
'Protection For APD' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForAPD;
|
||||
'APD Timeout Enabled' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.EnableAPDTimeoutForHosts;
|
||||
'APD Timeout (Seconds)' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmTerminateDelayForAPDSec;
|
||||
'Reaction on APD Cleared' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmReactionOnAPDCleared;
|
||||
'Protection For PDL' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForPDL
|
||||
}
|
||||
|
||||
# Create PSObject with the Hashtable
|
||||
$object = New-Object -TypeName PSObject -Prop $properties
|
||||
|
||||
# Show object
|
||||
return $object
|
||||
|
||||
}
|
||||
}
|
||||
322
Modules/VMCPFunctions/VMCPFunctions.psm1
Normal file
322
Modules/VMCPFunctions/VMCPFunctions.psm1
Normal file
@@ -0,0 +1,322 @@
|
||||
function Get-VMCPSettings {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 10/27/2015 9:25 PM
|
||||
Created by: Brian Graf
|
||||
Twitter: @vBrianGraf
|
||||
VMware Blog: blogs.vmware.com/powercli
|
||||
Personal Blog: www.vtagion.com
|
||||
|
||||
Modified on: 10/11/2016
|
||||
Modified by: Erwan Quélin
|
||||
Twitter: @erwanquelin
|
||||
Github: https://github.com/equelin
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function will allow users to view the VMCP settings for their clusters
|
||||
|
||||
.PARAMETER Cluster
|
||||
Cluster Name or Object
|
||||
|
||||
.PARAMETER Server
|
||||
vCenter server object
|
||||
|
||||
.EXAMPLE
|
||||
Get-VMCPSettings
|
||||
|
||||
This will show you the VMCP settings for all the clusters
|
||||
|
||||
.EXAMPLE
|
||||
Get-VMCPSettings -cluster LAB-CL
|
||||
|
||||
This will show you the VMCP settings of your cluster
|
||||
|
||||
.EXAMPLE
|
||||
Get-VMCPSettings -cluster (Get-Cluster Lab-CL)
|
||||
|
||||
This will show you the VMCP settings of your cluster
|
||||
|
||||
.EXAMPLE
|
||||
Get-Cluster | Get-VMCPSettings
|
||||
|
||||
This will show you the VMCP settings for all the clusters
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$True,
|
||||
ValueFromPipelineByPropertyName=$True,
|
||||
HelpMessage='What is the Cluster Name?')]
|
||||
$cluster = (Get-Cluster -Server $Server),
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[VMware.VimAutomation.Types.VIServer[]]$Server = $global:DefaultVIServers
|
||||
)
|
||||
|
||||
Process {
|
||||
|
||||
Foreach ($Clus in $Cluster) {
|
||||
|
||||
Write-Verbose "Processing Cluster $($Clus.Name)"
|
||||
|
||||
# Determine input and convert to ClusterImpl object
|
||||
Switch ($Clus.GetType().Name)
|
||||
{
|
||||
"string" {$CL = Get-Cluster $Clus -Server $Server -ErrorAction SilentlyContinue}
|
||||
"ClusterImpl" {$CL = $Clus}
|
||||
}
|
||||
|
||||
If ($CL) {
|
||||
# Work with the Cluster View
|
||||
$ClusterMod = Get-View -Id "ClusterComputeResource-$($CL.ExtensionData.MoRef.Value)" -Server $Server
|
||||
|
||||
# Create Hashtable with desired properties to return
|
||||
$properties = [ordered]@{
|
||||
'Cluster' = $ClusterMod.Name;
|
||||
'VMCP Status' = $clustermod.Configuration.DasConfig.VmComponentProtecting;
|
||||
'Protection For APD' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForAPD;
|
||||
'APD Timeout Enabled' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.EnableAPDTimeoutForHosts;
|
||||
'APD Timeout (Seconds)' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmTerminateDelayForAPDSec;
|
||||
'Reaction on APD Cleared' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmReactionOnAPDCleared;
|
||||
'Protection For PDL' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForPDL
|
||||
}
|
||||
|
||||
# Create PSObject with the Hashtable
|
||||
$object = New-Object -TypeName PSObject -Prop $properties
|
||||
|
||||
# Show object
|
||||
$object
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Set-VMCPSettings {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 10/27/2015 9:25 PM
|
||||
Created by: Brian Graf
|
||||
Twitter: @vBrianGraf
|
||||
VMware Blog: blogs.vmware.com/powercli
|
||||
Personal Blog: www.vtagion.com
|
||||
|
||||
Modified on: 10/11/2016
|
||||
Modified by: Erwan Quélin
|
||||
Twitter: @erwanquelin
|
||||
Github: https://github.com/equelin
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function will allow users to enable/disable VMCP and also allow
|
||||
them to configure the additional VMCP settings
|
||||
For each parameter, users should use the 'Tab' button to auto-fill the
|
||||
possible values.
|
||||
|
||||
.PARAMETER Cluster
|
||||
Cluster Name or Object
|
||||
|
||||
.PARAMETER enableVMCP
|
||||
Enable or disable VMCP
|
||||
|
||||
.PARAMETER VmStorageProtectionForPDL
|
||||
VM Storage Protection for PDL settings. Might be:
|
||||
- disabled
|
||||
- warning
|
||||
- restartAggressive
|
||||
|
||||
.PARAMETER VmStorageProtectionForAPD
|
||||
VM Storage Protection for APD settings. Might be:
|
||||
- disabled
|
||||
- restartConservative
|
||||
- restartAggressive
|
||||
- warning
|
||||
|
||||
.PARAMETER VmTerminateDelayForAPDSec
|
||||
VM Terminate Delay for APD (seconds).
|
||||
|
||||
.PARAMETER VmReactionOnAPDCleared
|
||||
VM reaction on APD Cleared. Might be:
|
||||
- reset
|
||||
- none
|
||||
|
||||
.PARAMETER Server
|
||||
vCenter server object
|
||||
|
||||
.EXAMPLE
|
||||
Set-VMCPSettings -cluster LAB-CL -enableVMCP:$True -VmStorageProtectionForPDL `
|
||||
restartAggressive -VmStorageProtectionForAPD restartAggressive `
|
||||
-VmTerminateDelayForAPDSec 2000 -VmReactionOnAPDCleared reset
|
||||
|
||||
This will enable VMCP and configure the Settings on cluster LAB-CL
|
||||
|
||||
.EXAMPLE
|
||||
Set-VMCPSettings -cluster LAB-CL -enableVMCP:$False -VmStorageProtectionForPDL `
|
||||
disabled -VmStorageProtectionForAPD disabled `
|
||||
-VmTerminateDelayForAPDSec 600 -VmReactionOnAPDCleared none
|
||||
|
||||
This will disable VMCP and configure the Settings on cluster LAB-CL
|
||||
|
||||
.EXAMPLE
|
||||
Set-VMCPSettings -enableVMCP:$False -VmStorageProtectionForPDL `
|
||||
disabled -VmStorageProtectionForAPD disabled `
|
||||
-VmTerminateDelayForAPDSec 600 -VmReactionOnAPDCleared none
|
||||
|
||||
This will disable VMCP and configure the Settings on all clusters available
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact="High")]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipeline=$True,
|
||||
ValueFromPipelineByPropertyName=$True,
|
||||
HelpMessage='What is the Cluster Name?')]
|
||||
$cluster,
|
||||
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='$True=Enabled $False=Disabled')]
|
||||
[bool]$enableVMCP,
|
||||
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Actions that can be taken in response to a PDL event')]
|
||||
[ValidateSet("disabled","warning","restartAggressive")]
|
||||
[string]$VmStorageProtectionForPDL,
|
||||
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Options available for an APD response')]
|
||||
[ValidateSet("disabled","restartConservative","restartAggressive","warning")]
|
||||
[string]$VmStorageProtectionForAPD,
|
||||
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Value in seconds')]
|
||||
[Int]$VmTerminateDelayForAPDSec,
|
||||
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='This setting will instruct vSphere HA to take a certain action if an APD event is cleared')]
|
||||
[ValidateSet("reset","none")]
|
||||
[string]$VmReactionOnAPDCleared,
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[VMware.VimAutomation.Types.VIServer[]]$Server = $global:DefaultVIServers
|
||||
)
|
||||
|
||||
Process {
|
||||
|
||||
Foreach ($Clus in $Cluster) {
|
||||
|
||||
Write-Verbose "Processing Cluster $Clus"
|
||||
|
||||
# Determine input and convert to ClusterImpl object
|
||||
Switch ($Clus.GetType().Name)
|
||||
{
|
||||
"string" {$CL = Get-Cluster $Clus -Server $Server -ErrorAction SilentlyContinue}
|
||||
"ClusterImpl" {$CL = $Clus}
|
||||
default {Throw 'Please provide a cluster name or object'}
|
||||
}
|
||||
|
||||
If ($CL) {
|
||||
|
||||
# Get the actual configuration of the Cluster
|
||||
$ActualSettings = Get-VMCPSettings -Cluster $CL -Server $Server
|
||||
|
||||
# Show actual settings in the verbose mode
|
||||
Write-Verbose "[$($CL.Name)] Actual VMCP settings "
|
||||
Write-Verbose $ActualSettings
|
||||
|
||||
# Create the object we will configure
|
||||
$settings = New-Object VMware.Vim.ClusterConfigSpecEx
|
||||
$settings.dasConfig = New-Object VMware.Vim.ClusterDasConfigInfo
|
||||
|
||||
# Based on $enableVMCP switch
|
||||
if ($enableVMCP -eq $false) {
|
||||
$settings.dasConfig.vmComponentProtecting = "disabled"
|
||||
}
|
||||
elseif ($enableVMCP -eq $true) {
|
||||
$settings.dasConfig.vmComponentProtecting = "enabled"
|
||||
}
|
||||
|
||||
#Create the VMCP object to work with
|
||||
$settings.dasConfig.defaultVmSettings = New-Object VMware.Vim.ClusterDasVmSettings
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings = New-Object VMware.Vim.ClusterVmComponentProtectionSettings
|
||||
|
||||
#Storage Protection For PDL
|
||||
If ($PSBoundParameters.ContainsKey('VmStorageProtectionForPDL')) {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForPDL = $VmStorageProtectionForPDL
|
||||
} else {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForPDL = $ActualSettings.'Protection For PDL'
|
||||
}
|
||||
|
||||
#Storage Protection for APD
|
||||
If ($PSBoundParameters.ContainsKey('VmStorageProtectionForAPD')) {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = $VmStorageProtectionForAPD
|
||||
} else {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = $ActualSettings.'Protection For APD'
|
||||
}
|
||||
|
||||
#Storage Protection for APD
|
||||
If ($PSBoundParameters.ContainsKey('VmStorageProtectionForAPD')) {
|
||||
switch ($VmStorageProtectionForAPD) {
|
||||
"disabled" {
|
||||
# If Disabled, there is no need to set enable Timeout Value
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'disabled'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $false
|
||||
}
|
||||
|
||||
"restartConservative" {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'restartConservative'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $true
|
||||
}
|
||||
|
||||
"restartAggressive" {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'restartAggressive'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $true
|
||||
}
|
||||
|
||||
"warning" {
|
||||
# If Warning, there is no need to enable the Timeout Value
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'warning'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = $ActualSettings.'Protection For APD'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $ActualSettings.'APD Timeout Enabled'
|
||||
}
|
||||
|
||||
#APD Timeout Enabled
|
||||
If ($PSBoundParameters.ContainsKey('VmTerminateDelayForAPDSec')) {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmTerminateDelayForAPDSec = $VmTerminateDelayForAPDSec
|
||||
} else {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmTerminateDelayForAPDSec = $ActualSettings.'APD Timeout (Seconds)'
|
||||
}
|
||||
|
||||
# Reaction On APD Cleared
|
||||
If ($PSBoundParameters.ContainsKey('VmReactionOnAPDCleared')) {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmReactionOnAPDCleared = "$VmReactionOnAPDCleared"
|
||||
} else {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmReactionOnAPDCleared = $ActualSettings.'Reaction on APD Cleared'
|
||||
}
|
||||
|
||||
# Execute API Call
|
||||
If ($pscmdlet.ShouldProcess($CL.Name,"Modify VMCP configuration")) {
|
||||
$modify = $true
|
||||
$ClusterMod = Get-View -Id "ClusterComputeResource-$($CL.ExtensionData.MoRef.Value)" -Server $Server
|
||||
$Task = $ClusterMod.ReconfigureComputeResource_Task($settings, $modify)
|
||||
}
|
||||
|
||||
# Wait for the reconfiguration task to finish to show the result
|
||||
If ($Task) {
|
||||
$TaskID = "Task-" + $($Task.Value)
|
||||
Get-Task -Id $TaskID -Server $Server | Wait-Task | Out-Null
|
||||
Get-VMCPSettings -Cluster $CL -Server $Server
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
6
Modules/VMFSIncrease/LICENSE.txt.URL
Normal file
6
Modules/VMFSIncrease/LICENSE.txt.URL
Normal file
@@ -0,0 +1,6 @@
|
||||
[InternetShortcut]
|
||||
URL=https://github.com/lucdekens/LogInsight/blob/v1.0/LICENSE.txt
|
||||
IDList=
|
||||
HotKey=0
|
||||
IconFile=C:\Users\ldekens\AppData\Local\Mozilla\Firefox\Profiles\2ahnnh1i.default\shortcutCache\ec4nFcIEAQBPFmSiPtTJ2w==.ico
|
||||
IconIndex=0
|
||||
18
Modules/VMFSIncrease/VMFSIncrease.psd1
Normal file
18
Modules/VMFSIncrease/VMFSIncrease.psd1
Normal file
@@ -0,0 +1,18 @@
|
||||
@{
|
||||
ModuleToProcess = 'VMFSIncrease.psm1'
|
||||
ModuleVersion = '1.0.0.0'
|
||||
GUID = '9f167385-c5c6-4a65-ac14-949c67519001'
|
||||
Author = 'Luc Dekens '
|
||||
CompanyName = 'Community'
|
||||
Copyright = '(c) 2016. All rights reserved.'
|
||||
Description = 'Expand and Extend VMFS DatastoresModule description'
|
||||
PowerShellVersion = '3.0'
|
||||
FunctionsToExport = 'Get-VmfsDatastoreInfo','Get-VmfsDatastoreIncrease','New-VmfsDatastoreIncrease'
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
Tags = @('VMFS','Expand','Extend','vSphere')
|
||||
LicenseUri = 'https://www.tldrlegal.com/l/mit'
|
||||
ProjectUri = 'https://github.com/lucdekens/VMFSIncrease'
|
||||
}
|
||||
}
|
||||
}
|
||||
247
Modules/VMFSIncrease/VMFSIncrease.psm1
Normal file
247
Modules/VMFSIncrease/VMFSIncrease.psm1
Normal file
@@ -0,0 +1,247 @@
|
||||
function Get-VmfsDatastoreInfo
|
||||
{
|
||||
[CmdletBinding(SupportsShouldProcess = $True)]
|
||||
param (
|
||||
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $True)]
|
||||
[PSObject]$Datastore
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
if ($Datastore -is [String])
|
||||
{
|
||||
$Datastore = Get-Datastore -Name $Datastore -ErrorAction SilentlyContinue
|
||||
}
|
||||
if ($Datastore -isnot [VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.Datastore])
|
||||
{
|
||||
Write-Error 'Invalid value for Datastore.'
|
||||
return
|
||||
}
|
||||
if ($Datastore.Type -ne 'VMFS')
|
||||
{
|
||||
Write-Error "$($Datastore.Name) is not a VMFS datastore"
|
||||
return
|
||||
}
|
||||
|
||||
# Get the Datastore System Manager from an ESXi that has the Datastore
|
||||
$esx = Get-View -Id ($Datastore.ExtensionData.Host | Get-Random | Select -ExpandProperty Key)
|
||||
$hsSys = Get-View -Id $esx.ConfigManager.StorageSystem
|
||||
|
||||
foreach ($extent in $Datastore.ExtensionData.Info.Vmfs.Extent)
|
||||
{
|
||||
$lun = $esx.Config.StorageDevice.ScsiLun | where{ $_.CanonicalName -eq $extent.DiskName }
|
||||
|
||||
$hdPartInfo = $hsSys.RetrieveDiskPartitionInfo($lun.DeviceName)
|
||||
$hdPartInfo[0].Layout.Partition | %{
|
||||
New-Object PSObject -Property ([ordered]@{
|
||||
Datastore = $Datastore.Name
|
||||
CanonicalName = $lun.CanonicalName
|
||||
Model = "$($lun.Vendor.TrimEnd(' ')).$($lun.Model.TrimEnd(' ')).$($lun.Revision.TrimEnd(' '))"
|
||||
DiskSizeGB = $hdPartInfo[0].Layout.Total.BlockSize * $hdPartInfo[0].Layout.Total.Block / 1GB
|
||||
DiskBlocks = $hdPartInfo[0].Layout.Total.Block
|
||||
DiskBlockMB = $hdPartInfo[0].Layout.Total.BlockSize/1MB
|
||||
PartitionFormat = $hdPartInfo[0].Spec.PartitionFormat
|
||||
Partition = if ($_.Partition -eq '') { '<free>' }else{ $_.Partition }
|
||||
Used = $extent.Partition -eq $_.Partition
|
||||
Type = $_.Type
|
||||
PartitionSizeGB = [math]::Round(($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize / 1GB, 1)
|
||||
PartitionBlocks = $_.End.Block - $_.Start.Block + 1
|
||||
PartitionBlockMB = $_.Start.BlockSize/1MB
|
||||
Start = $_.Start.Block
|
||||
End = $_.End.Block
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-VmfsDatastoreIncrease
|
||||
{
|
||||
[CmdletBinding(SupportsShouldProcess = $True)]
|
||||
param (
|
||||
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $True)]
|
||||
[PSObject]$Datastore
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
if ($Datastore -is [String])
|
||||
{
|
||||
$Datastore = Get-Datastore -Name $Datastore -ErrorAction SilentlyContinue
|
||||
}
|
||||
if ($Datastore -isnot [VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.Datastore])
|
||||
{
|
||||
Write-Error 'Invalid value for Datastore.'
|
||||
return
|
||||
}
|
||||
|
||||
if ($Datastore.Type -ne 'VMFS')
|
||||
{
|
||||
Write-Error "$($Datastore.Name) is not a VMFS datastore"
|
||||
return
|
||||
}
|
||||
|
||||
# Get the Datastore System Manager from an ESXi that has the Datastore
|
||||
$esx = Get-View -Id ($Datastore.ExtensionData.Host | Get-Random | Select -ExpandProperty Key)
|
||||
$hsSys = Get-View -Id $esx.ConfigManager.StorageSystem
|
||||
$hdSys = Get-View -Id $esx.ConfigManager.DatastoreSystem
|
||||
|
||||
$extents = $Datastore.ExtensionData.Info.Vmfs.Extent | Select -ExpandProperty DiskName
|
||||
|
||||
$hScsiDisk = $hdSys.QueryAvailableDisksForVmfs($Datastore.ExtensionData.MoRef)
|
||||
foreach ($disk in $hScsiDisk)
|
||||
{
|
||||
$partInfo = $hsSys.RetrieveDiskPartitionInfo($disk.DeviceName)
|
||||
$partUsed = ($partInfo[0].Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||
if ($extents -contains $disk.CanonicalName)
|
||||
{
|
||||
$incType = 'Expand'
|
||||
$vmfsExpOpt = $hdSys.QueryVmfsDatastoreExpandOptions($Datastore.ExtensionData.MoRef)
|
||||
$PartMax = ($vmfsExpOpt[0].Info.Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||
}
|
||||
else
|
||||
{
|
||||
$incType = 'Extend'
|
||||
$vmfsExtOpt = $hdSys.QueryVmfsDatastoreExtendOptions($Datastore.ExtensionData.MoRef, $disk.DevicePath, $null)
|
||||
$partMax = ($vmfsExpOpt[0].Info.Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||
}
|
||||
New-Object PSObject -Property ([ordered]@{
|
||||
Datastore = $Datastore.Name
|
||||
CanonicalName = $disk.CanonicalName
|
||||
Model = "$($disk.Vendor.TrimEnd(' ')).$($disk.Model.TrimEnd(' ')).$($disk.Revision.TrimEnd(' '))"
|
||||
DiskSizeGB = $partInfo[0].Layout.Total.BlockSize * $hdPartInfo[0].Layout.Total.Block / 1GB
|
||||
DiskBlocks = $partInfo[0].Layout.Total.Block
|
||||
DiskBlockMB = $partInfo[0].Layout.Total.BlockSize/1MB
|
||||
AvailableGB = [math]::Round($partMax - $partUsed, 2)
|
||||
Type = $incType
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function New-VmfsDatastoreIncrease
|
||||
{
|
||||
[CmdletBinding(SupportsShouldProcess = $True)]
|
||||
param (
|
||||
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $True)]
|
||||
[PSObject]$Datastore,
|
||||
[int]$IncreaseSizeGB,
|
||||
[Parameter(Position = 1)]
|
||||
[string]$CanonicalName,
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'Expand')]
|
||||
[switch]$Expand,
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'ExTend')]
|
||||
[switch]$Extend
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
if ($Datastore -is [String])
|
||||
{
|
||||
$Datastore = Get-Datastore -Name $Datastore -ErrorAction SilentlyContinue
|
||||
}
|
||||
if ($Datastore -isnot [VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.Datastore])
|
||||
{
|
||||
Write-Error 'Invalid value for Datastore.'
|
||||
return
|
||||
}
|
||||
|
||||
if ($Datastore.Type -ne 'VMFS')
|
||||
{
|
||||
Write-Error "$($Datastore.Name) is not a VMFS datastore"
|
||||
return
|
||||
}
|
||||
|
||||
# Get the Datastore System Manager from an ESXi that has the Datastore
|
||||
$esx = Get-View -Id ($Datastore.ExtensionData.Host | Get-Random | Select -ExpandProperty Key)
|
||||
$hsSys = Get-View -Id $esx.ConfigManager.StorageSystem
|
||||
$hdSys = Get-View -Id $esx.ConfigManager.DatastoreSystem
|
||||
|
||||
$extents = $Datastore.ExtensionData.Info.Vmfs.Extent | Select -ExpandProperty DiskName
|
||||
|
||||
$hScsiDisk = $hdSys.QueryAvailableDisksForVmfs($Datastore.ExtensionData.MoRef)
|
||||
|
||||
# Expand or Extend
|
||||
switch ($PSCmdlet.ParameterSetName)
|
||||
{
|
||||
'Expand' {
|
||||
$expOpt = $hdSys.QueryVmfsDatastoreExpandOptions($Datastore.ExtensionData.MoRef)
|
||||
if ($CanonicalName)
|
||||
{
|
||||
$dsOpt = $expOpt | where{ $_.Spec.Extent.DiskName -eq $CanonicalName }
|
||||
}
|
||||
else
|
||||
{
|
||||
$dsOpt = $expOpt | Sort-Object -Property { $_.Spec.Extent.Diskname } | select -first 1
|
||||
}
|
||||
if ($IncreaseSizeGB -ne 0)
|
||||
{
|
||||
$lun = $hScsiDisk | where{ $_.CanonicalName -eq $dsOpt.Spec.Extent.DiskName }
|
||||
$partInfo = $hsSys.RetrieveDiskPartitionInfo($lun.DeviceName)
|
||||
$partMax = ($vmfsExpOpt[0].Info.Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||
$partUsed = ($partInfo[0].Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||
if (($partMax - $partUsed) -ge $IncreaseSizeGB)
|
||||
{
|
||||
$spec = $dsOpt.Spec
|
||||
$spec.Partition.Partition[0].EndSector -= ([math]::Floor(($partMax - $partUsed - $IncreaseSizeGB) * 1GB/512))
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Error "Requested expand size $($IncreaseSizeGB)GB not available on $($lun.CanonicalName)"
|
||||
return
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$spec = $dsOpt.Spec
|
||||
}
|
||||
$hdSys.ExpandVmfsDatastore($Datastore.ExtensionData.MoRef, $spec)
|
||||
}
|
||||
'Extend' {
|
||||
if ($CanonicalName)
|
||||
{
|
||||
$lun = $hScsiDisk | where{ $extents -notcontains $_.CanonicalName -and $_.CanonicalName -eq $CanonicalName }
|
||||
}
|
||||
else
|
||||
{
|
||||
$lun = $hScsiDisk | where{ $extents -notcontains $_.CanonicalName } | Sort-Object -Property CanonicalName | select -First 1
|
||||
}
|
||||
if (!$lun)
|
||||
{
|
||||
Write-Error "No valid LUN provided or found for extent"
|
||||
return
|
||||
}
|
||||
$vmfsExtOpt = $hdSys.QueryVmfsDatastoreExtendOptions($Datastore.ExtensionData.MoRef, $lun.DevicePath, $null)
|
||||
if ($IncreaseSizeGB -ne 0)
|
||||
{
|
||||
$partInfo = $hsSys.RetrieveDiskPartitionInfo($lun.DeviceName)
|
||||
$partMax = ($vmfsExpOpt[0].Info.Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||
if ($partMax -ge $IncreaseSizeGB)
|
||||
{
|
||||
$spec = $vmfsExtOpt[0].Spec
|
||||
$spec.Partition.Partition[0].EndSector = $spec.Partition.Partition[0].StartSector + [math]::Floor($IncreaseSizeGB * 1GB / 512)
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Error "No valid LUN for extent with $($IncreaseSizeGB)GB space found"
|
||||
return
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$spec = $vmfsExtOpt.Spec
|
||||
}
|
||||
|
||||
$hdSys.ExtendVmfsDatastore($Datastore.ExtensionData.MoRef, $spec)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function Get-VmfsDatastoreInfo,Get-VmfsDatastoreIncrease,New-VmfsDatastoreIncrease
|
||||
473
Modules/VMFSIncrease/en-US/VMFSIncrease.psm1-Help.xml
Normal file
473
Modules/VMFSIncrease/en-US/VMFSIncrease.psm1-Help.xml
Normal file
@@ -0,0 +1,473 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<helpItems xmlns="http://msh" schema="maml">
|
||||
<!--Edited with: SAPIEN PowerShell HelpWriter 2015 v1.0.16-->
|
||||
<!--Generated by: SAPIEN PowerShell HelpWriter 2015 v1.0.16-->
|
||||
<!--
|
||||
Module: VMFSIncrease
|
||||
Version: 1.0.0.0
|
||||
-->
|
||||
<!--All Commands-->
|
||||
<command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
|
||||
<!--Command-->
|
||||
<command:details>
|
||||
<command:name>Get-VmfsDatastoreInfo</command:name>
|
||||
<maml:description>
|
||||
<maml:para>Provides partition information for all the extents in the datastore.</maml:para>
|
||||
</maml:description>
|
||||
<maml:copyright>
|
||||
<maml:para/>
|
||||
</maml:copyright>
|
||||
<command:verb>Get</command:verb>
|
||||
<command:noun>VmfsDatastoreInfo</command:noun>
|
||||
<dev:version/>
|
||||
</command:details>
|
||||
<maml:description>
|
||||
<maml:para>The function will display partition information for all the extents used by the datastore.</maml:para>
|
||||
</maml:description>
|
||||
<command:syntax>
|
||||
<!--Parameter Sets-->
|
||||
<command:syntaxItem>
|
||||
<maml:name>Get-VmfsDatastoreInfo</maml:name>
|
||||
<command:parameter required="true" variableLength="false" globbing="false" pipelineInput="True (ByValue)" position="0" aliases="">
|
||||
<maml:name>Datastore</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The name of the Datastore or a PowerCLI Datastore object</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="true" variableLength="false">PSObject</command:parameterValue>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
</command:syntaxItem>
|
||||
</command:syntax>
|
||||
<command:parameters>
|
||||
<!--All Parameters-->
|
||||
<command:parameter required="true" variableLength="false" globbing="false" pipelineInput="True (ByValue)" position="0" aliases="">
|
||||
<maml:name>Datastore</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The name of the Datastore or a PowerCLI Datastore object</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="true" variableLength="false">PSObject</command:parameterValue>
|
||||
<dev:type>
|
||||
<maml:name>PSObject</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
</command:parameters>
|
||||
<command:inputTypes>
|
||||
<!--Inputs-->
|
||||
<command:inputType>
|
||||
<dev:type>
|
||||
<maml:name>System.Management.Automation.PSObject
|
||||
</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<maml:description>
|
||||
<maml:para/>
|
||||
</maml:description>
|
||||
</command:inputType>
|
||||
</command:inputTypes>
|
||||
<command:returnValues>
|
||||
<!--Outputs-->
|
||||
<command:returnValue>
|
||||
<dev:type>
|
||||
<maml:name>System.Object</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<maml:description>
|
||||
<maml:para/>
|
||||
</maml:description>
|
||||
</command:returnValue>
|
||||
</command:returnValues>
|
||||
<command:examples>
|
||||
<!--Examples-->
|
||||
<command:example>
|
||||
<maml:title>-------------------------- EXAMPLE 1 --------------------------</maml:title>
|
||||
<maml:introduction>
|
||||
<maml:para>PS C:\></maml:para>
|
||||
</maml:introduction>
|
||||
<dev:code>Get-VmfsDatastoreInfo -Datastore MyDS</dev:code>
|
||||
<dev:remarks>
|
||||
<maml:para>Will return partition information for the Datastore named MyDS</maml:para>
|
||||
</dev:remarks>
|
||||
</command:example>
|
||||
<command:example>
|
||||
<maml:title>-------------------------- EXAMPLE 2 --------------------------</maml:title>
|
||||
<maml:introduction>
|
||||
<maml:para>PS C:\></maml:para>
|
||||
</maml:introduction>
|
||||
<dev:code>Get-Datastore -Name My* | Get-VmfsDatastoreInfo</dev:code>
|
||||
<dev:remarks>
|
||||
<maml:para>This example will return partition information for all the Datastore objects that are returned by the Get-Datastore PowerCLI cmdlet</maml:para>
|
||||
</dev:remarks>
|
||||
</command:example>
|
||||
</command:examples>
|
||||
</command:command>
|
||||
<command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
|
||||
<!--Command-->
|
||||
<command:details>
|
||||
<command:name>Get-VmfsDatastoreIncrease</command:name>
|
||||
<maml:description>
|
||||
<maml:para>Displays the increase options for a datastore</maml:para>
|
||||
</maml:description>
|
||||
<maml:copyright>
|
||||
<maml:para/>
|
||||
</maml:copyright>
|
||||
<command:verb>Get</command:verb>
|
||||
<command:noun>VmfsDatastoreIncrease</command:noun>
|
||||
<dev:version/>
|
||||
</command:details>
|
||||
<maml:description>
|
||||
<maml:para>The function will provide all the Expand and Extend options for a specific datastore</maml:para>
|
||||
</maml:description>
|
||||
<command:syntax>
|
||||
<!--Parameter Sets-->
|
||||
<command:syntaxItem>
|
||||
<maml:name>Get-VmfsDatastoreIncrease</maml:name>
|
||||
<command:parameter required="true" variableLength="false" globbing="false" pipelineInput="True (ByValue)" position="0" aliases="">
|
||||
<maml:name>Datastore</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The name of the Datastore or a PowerCLI Datastore object</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="true" variableLength="false">PSObject</command:parameterValue>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
</command:syntaxItem>
|
||||
</command:syntax>
|
||||
<command:parameters>
|
||||
<!--All Parameters-->
|
||||
<command:parameter required="true" variableLength="false" globbing="false" pipelineInput="True (ByValue)" position="0" aliases="">
|
||||
<maml:name>Datastore</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The name of the Datastore or a PowerCLI Datastore object</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="true" variableLength="false">PSObject</command:parameterValue>
|
||||
<dev:type>
|
||||
<maml:name>PSObject</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
</command:parameters>
|
||||
<command:inputTypes>
|
||||
<!--Inputs-->
|
||||
<command:inputType>
|
||||
<dev:type>
|
||||
<maml:name>System.Management.Automation.PSObject
|
||||
</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<maml:description>
|
||||
<maml:para/>
|
||||
</maml:description>
|
||||
</command:inputType>
|
||||
</command:inputTypes>
|
||||
<command:returnValues>
|
||||
<!--Outputs-->
|
||||
<command:returnValue>
|
||||
<dev:type>
|
||||
<maml:name>System.Object</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<maml:description>
|
||||
<maml:para/>
|
||||
</maml:description>
|
||||
</command:returnValue>
|
||||
</command:returnValues>
|
||||
<command:examples>
|
||||
<!--Examples-->
|
||||
<command:example>
|
||||
<maml:title>-------------------------- EXAMPLE 1 --------------------------</maml:title>
|
||||
<maml:introduction>
|
||||
<maml:para>PS C:\></maml:para>
|
||||
</maml:introduction>
|
||||
<dev:code>Get-VmfsDatastoreIncrease -Datastore MyDS</dev:code>
|
||||
<dev:remarks>
|
||||
<maml:para>The exmaple will list all Expand and Extend options available for the Datastore, named MyDS</maml:para>
|
||||
</dev:remarks>
|
||||
</command:example>
|
||||
<command:example>
|
||||
<maml:title>-------------------------- EXAMPLE 2 --------------------------</maml:title>
|
||||
<maml:introduction>
|
||||
<maml:para>PS C:\></maml:para>
|
||||
</maml:introduction>
|
||||
<dev:code>Get-Datastore -Name MyDS* | Get-VmfsDatastoreIncrease</dev:code>
|
||||
<dev:remarks>
|
||||
<maml:para>The Expand and Extend options for all Datastore retruned by the PowerCLI Get-Datastore will be returned.</maml:para>
|
||||
</dev:remarks>
|
||||
</command:example>
|
||||
</command:examples>
|
||||
</command:command>
|
||||
<command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
|
||||
<!--Command-->
|
||||
<command:details>
|
||||
<command:name>New-VmfsDatastoreIncrease</command:name>
|
||||
<maml:description>
|
||||
<maml:para>Increase the capacity of a Datastore</maml:para>
|
||||
</maml:description>
|
||||
<maml:copyright>
|
||||
<maml:para/>
|
||||
</maml:copyright>
|
||||
<command:verb>New</command:verb>
|
||||
<command:noun>VmfsDatastoreIncrease</command:noun>
|
||||
<dev:version/>
|
||||
</command:details>
|
||||
<maml:description>
|
||||
<maml:para>The capacity of the Datastore in increased through an Expand or an Extend.
|
||||
To allow successful completion there shall be free capacity on one of the Extents, or there shall be free LUNs available.
|
||||
With the Expand or Extend switches the caller selects which type of capacity increase is used.</maml:para>
|
||||
</maml:description>
|
||||
<command:syntax>
|
||||
<!--Parameter Sets-->
|
||||
<command:syntaxItem>
|
||||
<maml:name>New-VmfsDatastoreIncrease</maml:name>
|
||||
<command:parameter required="true" variableLength="false" globbing="false" pipelineInput="True (ByValue)" position="0" aliases="">
|
||||
<maml:name>Datastore</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The name of the Datastore or a PowerCLI Datastore object</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="true" variableLength="false">PSObject</command:parameterValue>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
<command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="1" aliases="">
|
||||
<maml:name>CanonicalName</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The Canonical name of the LUN on which to create a new Extent, or the name of the LUN on which to apply the Expansion.
|
||||
If this parameter is not provided, the function will sort the available LUN alphanumerically on the Canonical names and slect the first one.</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="false" variableLength="false">String</command:parameterValue>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
<command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="">
|
||||
<maml:name>IncreaseSizeGB</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The amount of GB by which to increase the size of the Datastore.
|
||||
If this parameter is not used, all of the available Expand or Extend diskspace will be used.</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="false" variableLength="false">Int32</command:parameterValue>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
<command:parameter required="true" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="">
|
||||
<maml:name>Expand</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>A switch to indicate if the Datastore shall be Expanded</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="false" variableLength="false">SwitchParameter</command:parameterValue>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
</command:syntaxItem>
|
||||
<command:syntaxItem>
|
||||
<maml:name>New-VmfsDatastoreIncrease</maml:name>
|
||||
<command:parameter required="true" variableLength="false" globbing="false" pipelineInput="True (ByValue)" position="0" aliases="">
|
||||
<maml:name>Datastore</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The name of the Datastore or a PowerCLI Datastore object</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="true" variableLength="false">PSObject</command:parameterValue>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
<command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="1" aliases="">
|
||||
<maml:name>CanonicalName</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The Canonical name of the LUN on which to create a new Extent, or the name of the LUN on which to apply the Expansion.
|
||||
If this parameter is not provided, the function will sort the available LUN alphanumerically on the Canonical names and slect the first one.</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="false" variableLength="false">String</command:parameterValue>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
<command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="">
|
||||
<maml:name>IncreaseSizeGB</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The amount of GB by which to increase the size of the Datastore.
|
||||
If this parameter is not used, all of the available Expand or Extend diskspace will be used.</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="false" variableLength="false">Int32</command:parameterValue>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
<command:parameter required="true" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="">
|
||||
<maml:name>Extend</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>A switch to indicate if the Datastore shall be Extended</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="false" variableLength="false">SwitchParameter</command:parameterValue>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
</command:syntaxItem>
|
||||
</command:syntax>
|
||||
<command:parameters>
|
||||
<!--All Parameters-->
|
||||
<command:parameter required="true" variableLength="false" globbing="false" pipelineInput="True (ByValue)" position="0" aliases="">
|
||||
<maml:name>Datastore</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The name of the Datastore or a PowerCLI Datastore object</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="true" variableLength="false">PSObject</command:parameterValue>
|
||||
<dev:type>
|
||||
<maml:name>PSObject</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
<command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="">
|
||||
<maml:name>IncreaseSizeGB</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The amount of GB by which to increase the size of the Datastore.
|
||||
If this parameter is not used, all of the available Expand or Extend diskspace will be used.</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="false" variableLength="false">Int32</command:parameterValue>
|
||||
<dev:type>
|
||||
<maml:name>Int32</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
<command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="1" aliases="">
|
||||
<maml:name>CanonicalName</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>The Canonical name of the LUN on which to create a new Extent, or the name of the LUN on which to apply the Expansion.
|
||||
If this parameter is not provided, the function will sort the available LUN alphanumerically on the Canonical names and slect the first one.</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="false" variableLength="false">String</command:parameterValue>
|
||||
<dev:type>
|
||||
<maml:name>String</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
<command:parameter required="true" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="">
|
||||
<maml:name>Expand</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>A switch to indicate if the Datastore shall be Expanded</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="true" variableLength="false">SwitchParameter</command:parameterValue>
|
||||
<dev:type>
|
||||
<maml:name>SwitchParameter</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
<command:parameter required="true" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="">
|
||||
<maml:name>Extend</maml:name>
|
||||
<maml:description>
|
||||
<maml:para>A switch to indicate if the Datastore shall be Extended</maml:para>
|
||||
</maml:description>
|
||||
<command:parameterValue required="true" variableLength="false">SwitchParameter</command:parameterValue>
|
||||
<dev:type>
|
||||
<maml:name>SwitchParameter</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<dev:defaultValue>
|
||||
</dev:defaultValue>
|
||||
</command:parameter>
|
||||
</command:parameters>
|
||||
<command:inputTypes>
|
||||
<!--Inputs-->
|
||||
<command:inputType>
|
||||
<dev:type>
|
||||
<maml:name>System.Management.Automation.PSObject
|
||||
</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<maml:description>
|
||||
<maml:para/>
|
||||
</maml:description>
|
||||
</command:inputType>
|
||||
</command:inputTypes>
|
||||
<command:returnValues>
|
||||
<!--Outputs-->
|
||||
<command:returnValue>
|
||||
<dev:type>
|
||||
<maml:name>System.Object</maml:name>
|
||||
<maml:uri/>
|
||||
</dev:type>
|
||||
<maml:description>
|
||||
<maml:para/>
|
||||
</maml:description>
|
||||
</command:returnValue>
|
||||
</command:returnValues>
|
||||
<command:examples>
|
||||
<!--Examples-->
|
||||
<command:example>
|
||||
<maml:title>-------------------------- EXAMPLE 1 --------------------------</maml:title>
|
||||
<maml:introduction>
|
||||
<maml:para>PS C:\></maml:para>
|
||||
</maml:introduction>
|
||||
<dev:code>New-VmfsDatastoreIncrease -Datastore MyDS -Expand</dev:code>
|
||||
<dev:remarks>
|
||||
<maml:para>The capacity of the Datastore, named MyDS, will be Expanded with all available free space on the first extent of the Datastore.</maml:para>
|
||||
</dev:remarks>
|
||||
</command:example>
|
||||
<command:example>
|
||||
<maml:title>-------------------------- EXAMPLE 2 --------------------------</maml:title>
|
||||
<maml:introduction>
|
||||
<maml:para>PS C:\></maml:para>
|
||||
</maml:introduction>
|
||||
<dev:code>New-VmfsDatastoreIncrease -Name MyDS -Expand -IncreaseSizeGB 25</dev:code>
|
||||
<dev:remarks>
|
||||
<maml:para>The capacity of the Datastore, named MyDS, will be Expanded with 25GB on the first extent of the Datastore.
|
||||
Provided if course, this amount of free space is available.</maml:para>
|
||||
</dev:remarks>
|
||||
</command:example>
|
||||
<command:example>
|
||||
<maml:title>-------------------------- EXAMPLE 3 --------------------------</maml:title>
|
||||
<maml:introduction>
|
||||
<maml:para>PS C:\></maml:para>
|
||||
</maml:introduction>
|
||||
<dev:code>New-VmfsDatastoreIncrease -Datastore 'TestDS' -Expand -IncreaseSizeGB 15 -CanonicalName 'naa.600507680180732f1800000000000011'</dev:code>
|
||||
<dev:remarks>
|
||||
<maml:para>The capacity of the Datastore MyDS will be increased with 15GB on the extent with the Canonicalname naa.600507680180732f1800000000000011</maml:para>
|
||||
</dev:remarks>
|
||||
</command:example>
|
||||
<command:example>
|
||||
<maml:title>-------------------------- EXAMPLE 4 --------------------------</maml:title>
|
||||
<maml:introduction>
|
||||
<maml:para>PS C:\></maml:para>
|
||||
</maml:introduction>
|
||||
<dev:code>New-VmfsDatastoreIncrease -Datastore MyDS -Expand -CanonicalName 'naa.600507680180732f1800000000000012'</dev:code>
|
||||
<dev:remarks>
|
||||
<maml:para>The capacity of the Datastore MyDS will be increased with all available free space on the extent with the Canonicalname naa.600507680180732f1800000000000012</maml:para>
|
||||
</dev:remarks>
|
||||
</command:example>
|
||||
<command:example>
|
||||
<maml:title>-------------------------- EXAMPLE 5 --------------------------</maml:title>
|
||||
<maml:introduction>
|
||||
<maml:para>PS C:\></maml:para>
|
||||
</maml:introduction>
|
||||
<dev:code>New-VmfsDatastoreIncrease -Datastore MyDS -Extend</dev:code>
|
||||
<dev:remarks>
|
||||
<maml:para>A new Extent will be added to Datastore MyDS.
|
||||
All available free space of the LUN will be allocated.
|
||||
The available LUNs are ordered alphanumerically by their Canonicalname, and the first LUN is used.</maml:para>
|
||||
</dev:remarks>
|
||||
</command:example>
|
||||
<command:example>
|
||||
<maml:title>-------------------------- EXAMPLE 6 --------------------------</maml:title>
|
||||
<maml:introduction>
|
||||
<maml:para>PS C:\></maml:para>
|
||||
</maml:introduction>
|
||||
<dev:code>Get-Datastore -Name MyDS | New-VmfsDatastoreIncrease -Extend -IncreaseSizeGB 50</dev:code>
|
||||
<dev:remarks>
|
||||
<maml:para>The capacity of the Datastore returned by the PowerCLI Get-Datastore cmdlet will be increased by 50GB.
|
||||
This is done by adding a new Extent to the Datastore.
|
||||
The available LUNs are ordered alphanumerically by their Canonicalname, and the first LUN is used.</maml:para>
|
||||
</dev:remarks>
|
||||
</command:example>
|
||||
</command:examples>
|
||||
</command:command>
|
||||
<!--Generated by: SAPIEN PowerShell HelpWriter 2015 v1.0.16-->
|
||||
</helpItems>
|
||||
13
Modules/VMFSIncrease/en-US/about_VMFSIncrease.help.txt
Normal file
13
Modules/VMFSIncrease/en-US/about_VMFSIncrease.help.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
TOPIC
|
||||
VMFSIncrease
|
||||
|
||||
SYNOPSIS
|
||||
The VMFSIncrease module offers the same functionality that is available
|
||||
through the Increase button in the vSphere Web Client.
|
||||
|
||||
DESCRIPTION
|
||||
The VMFSIncrease offers functionality that allows to Expand or Extend
|
||||
VMFS Datastores. The module uses the vSphere API to implement this functionality.
|
||||
|
||||
SEE ALSO
|
||||
http://www.lucd.info/2016/07/29/vmfs-datastores-expand-and-extend
|
||||
1149
Modules/VMToolsManagement/VMToolsManagement.psm1
Normal file
1149
Modules/VMToolsManagement/VMToolsManagement.psm1
Normal file
File diff suppressed because it is too large
Load Diff
40
Modules/VMware-vCD-Module/README.md
Normal file
40
Modules/VMware-vCD-Module/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
VMware-vCD-Module PowerShell Module
|
||||
===================================
|
||||
|
||||

|
||||
|
||||
# About
|
||||
|
||||
## Project Owner:
|
||||
|
||||
Markus Kraus [@vMarkus_K](https://twitter.com/vMarkus_K)
|
||||
|
||||
MY CLOUD-(R)EVOLUTION [mycloudrevolution.com](http://mycloudrevolution.com/)
|
||||
|
||||
|
||||
## Project WebSite:
|
||||
[PowerCLI vCloud Director Customer Provisioning](https://mycloudrevolution.com/2017/06/13/powercli-vcloud-director-customer-provisioning/)
|
||||
|
||||
[PowerCLI – Create vCloud Director Edge Gateway](https://mycloudrevolution.com/2017/06/27/powercli-create-vcloud-director-edge-gateway/)
|
||||
|
||||
|
||||
## Project Documentation:
|
||||
|
||||
[Read the Docs - VMware-vCD-Module](http://vmware-vcd-module.readthedocs.io/)
|
||||
|
||||
## Project Description:
|
||||
|
||||
The 'VMware-vCD-Module' PowerShell Module is focused on the initial creation of VMware vCloud Director Objects like Org, Org User, Org VDC with External Networks or Edge Gateway.
|
||||
|
||||
All Functions in this Module can be used as standalone Cmdlet but also the ``Invoke-My OnBoarding`` Functions to process a JSON File and create all Objects at once.
|
||||
|
||||
### Fully tested Versions:
|
||||
|
||||
Powershell: v4, v5
|
||||
|
||||
PowerCLI: 6.5.1
|
||||
|
||||
VMware vCloud Director: 8.10.1
|
||||
|
||||
|
||||
|
||||
127
Modules/VMware-vCD-Module/VMware-vCD-Module.psd1
Normal file
127
Modules/VMware-vCD-Module/VMware-vCD-Module.psd1
Normal file
@@ -0,0 +1,127 @@
|
||||
#
|
||||
# Modulmanifest für das Modul "PSGet_VMware-vCD-Module"
|
||||
#
|
||||
# Generiert von: Markus
|
||||
#
|
||||
# Generiert am: 6/11/2017
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Die diesem Manifest zugeordnete Skript- oder Binärmoduldatei.
|
||||
# RootModule = ''
|
||||
|
||||
# Die Versionsnummer dieses Moduls
|
||||
ModuleVersion = '1.0.0'
|
||||
|
||||
# ID zur eindeutigen Kennzeichnung dieses Moduls
|
||||
GUID = '1ef8a2de-ca22-4c88-8cdb-e00f35007d2a'
|
||||
|
||||
# Autor dieses Moduls
|
||||
Author = 'Markus'
|
||||
|
||||
# Unternehmen oder Hersteller dieses Moduls
|
||||
CompanyName = 'mycloudrevolution.com'
|
||||
|
||||
# Urheberrechtserklärung für dieses Modul
|
||||
Copyright = '(c) 2017 Markus. Alle Rechte vorbehalten.'
|
||||
|
||||
# Beschreibung der von diesem Modul bereitgestellten Funktionen
|
||||
# Description = ''
|
||||
|
||||
# Die für dieses Modul mindestens erforderliche Version des Windows PowerShell-Moduls
|
||||
# PowerShellVersion = ''
|
||||
|
||||
# Der Name des für dieses Modul erforderlichen Windows PowerShell-Hosts
|
||||
# PowerShellHostName = ''
|
||||
|
||||
# Die für dieses Modul mindestens erforderliche Version des Windows PowerShell-Hosts
|
||||
# PowerShellHostVersion = ''
|
||||
|
||||
# Die für dieses Modul mindestens erforderliche Microsoft .NET Framework-Version
|
||||
# DotNetFrameworkVersion = ''
|
||||
|
||||
# Die für dieses Modul mindestens erforderliche Version der CLR (Common Language Runtime)
|
||||
# CLRVersion = ''
|
||||
|
||||
# Die für dieses Modul erforderliche Prozessorarchitektur ("Keine", "X86", "Amd64").
|
||||
# ProcessorArchitecture = ''
|
||||
|
||||
# Die Module, die vor dem Importieren dieses Moduls in die globale Umgebung geladen werden müssen
|
||||
# RequiredModules = @()
|
||||
|
||||
# Die Assemblys, die vor dem Importieren dieses Moduls geladen werden müssen
|
||||
# RequiredAssemblies = @()
|
||||
|
||||
# Die Skriptdateien (PS1-Dateien), die vor dem Importieren dieses Moduls in der Umgebung des Aufrufers ausgeführt werden.
|
||||
# ScriptsToProcess = @()
|
||||
|
||||
# Die Typdateien (.ps1xml), die beim Importieren dieses Moduls geladen werden sollen
|
||||
# TypesToProcess = @()
|
||||
|
||||
# Die Formatdateien (.ps1xml), die beim Importieren dieses Moduls geladen werden sollen
|
||||
# FormatsToProcess = @()
|
||||
|
||||
# Die Module, die als geschachtelte Module des in "RootModule/ModuleToProcess" angegebenen Moduls importiert werden sollen.
|
||||
NestedModules = @('functions\Invoke-MyOnBoarding.psm1',
|
||||
'functions\New-MyEdgeGateway.psm1',
|
||||
'functions\New-MyOrg.psm1',
|
||||
'functions\New-MyOrgAdmin.psm1',
|
||||
'functions\New-MyOrgVdc.psm1')
|
||||
|
||||
# Aus diesem Modul zu exportierende Funktionen
|
||||
FunctionsToExport = 'Invoke-MyOnBoarding', 'New-MyEdgeGateway', 'New-MyOrg', 'New-MyOrgAdmin', 'New-MyOrgVdc'
|
||||
|
||||
# Aus diesem Modul zu exportierende Cmdlets
|
||||
CmdletsToExport = '*'
|
||||
|
||||
# Die aus diesem Modul zu exportierenden Variablen
|
||||
VariablesToExport = '*'
|
||||
|
||||
# Aus diesem Modul zu exportierende Aliase
|
||||
AliasesToExport = '*'
|
||||
|
||||
# Aus diesem Modul zu exportierende DSC-Ressourcen
|
||||
# DscResourcesToExport = @()
|
||||
|
||||
# Liste aller Module in diesem Modulpaket
|
||||
# ModuleList = @()
|
||||
|
||||
# Liste aller Dateien in diesem Modulpaket
|
||||
# FileList = @()
|
||||
|
||||
# Die privaten Daten, die an das in "RootModule/ModuleToProcess" angegebene Modul übergeben werden sollen. Diese können auch eine PSData-Hashtabelle mit zusätzlichen von PowerShell verwendeten Modulmetadaten enthalten.
|
||||
PrivateData = @{
|
||||
|
||||
PSData = @{
|
||||
|
||||
# Tags applied to this module. These help with module discovery in online galleries.
|
||||
# Tags = @()
|
||||
|
||||
# A URL to the license for this module.
|
||||
# LicenseUri = ''
|
||||
|
||||
# A URL to the main website for this project.
|
||||
# ProjectUri = ''
|
||||
|
||||
# A URL to an icon representing this module.
|
||||
# IconUri = ''
|
||||
|
||||
# ReleaseNotes of this module
|
||||
# ReleaseNotes = ''
|
||||
|
||||
# External dependent modules of this module
|
||||
# ExternalModuleDependencies = ''
|
||||
|
||||
} # End of PSData hashtable
|
||||
|
||||
} # End of PrivateData hashtable
|
||||
|
||||
# HelpInfo-URI dieses Moduls
|
||||
# HelpInfoURI = ''
|
||||
|
||||
# Standardpräfix für Befehle, die aus diesem Modul exportiert werden. Das Standardpräfix kann mit "Import-Module -Prefix" überschrieben werden.
|
||||
# DefaultCommandPrefix = ''
|
||||
|
||||
}
|
||||
|
||||
30
Modules/VMware-vCD-Module/examples/OnBoarding.json
Normal file
30
Modules/VMware-vCD-Module/examples/OnBoarding.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"Org": {
|
||||
"Name":"TestOrg",
|
||||
"FullName": "Test Org",
|
||||
"Description":"Automation Test Org"
|
||||
},
|
||||
"OrgAdmin": {
|
||||
"Name":"TestOrgAdmin",
|
||||
"Pasword": "myPassword1!",
|
||||
"FullName":"Test OrgAdmin",
|
||||
"EmailAddress":"test@admin.org"
|
||||
},
|
||||
"OrgVdc": {
|
||||
"Name":"TestOrgVdc",
|
||||
"FixedSize": "M",
|
||||
"CPULimit": "1000",
|
||||
"MEMLimit":"1024",
|
||||
"StorageLimit":"1024",
|
||||
"StorageProfile":"Standard-DC01",
|
||||
"ProviderVDC":"Provider-VDC-DC01",
|
||||
"NetworkPool":"Provider-VDC-DC01-NetPool",
|
||||
"ExternalNetwork": "External-OrgVdcNet",
|
||||
"EdgeGateway": "Yes",
|
||||
"IPAddress":"192.168.100.1",
|
||||
"SubnetMask":"255.255.255.0",
|
||||
"Gateway":"192.168.100.254",
|
||||
"IPRangeStart":"192.168.100.2",
|
||||
"IPRangeEnd":"192.168.100.3"
|
||||
}
|
||||
}
|
||||
191
Modules/VMware-vCD-Module/functions/Invoke-MyOnBoarding.psm1
Normal file
191
Modules/VMware-vCD-Module/functions/Invoke-MyOnBoarding.psm1
Normal file
@@ -0,0 +1,191 @@
|
||||
#Requires -Version 4
|
||||
#Requires -Modules VMware.VimAutomation.Cloud, @{ModuleName="VMware.VimAutomation.Cloud";ModuleVersion="6.3.0.0"}
|
||||
Function Invoke-MyOnBoarding {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates all vCD Objecst for a new IAAS Customer
|
||||
|
||||
.DESCRIPTION
|
||||
Creates all vCD Objects for a new IAAS Customer
|
||||
|
||||
All Objects are:
|
||||
* Org
|
||||
* Default Org Admin
|
||||
* Org VDC
|
||||
** Private Catalog
|
||||
** Optional Bridged Network
|
||||
|
||||
JSON Config Example:
|
||||
|
||||
{
|
||||
"Org": {
|
||||
"Name":"TestOrg",
|
||||
"FullName": "Test Org",
|
||||
"Description":"Automation Test Org"
|
||||
},
|
||||
"OrgAdmin": {
|
||||
"Name":"TestOrgAdmin",
|
||||
"Pasword": "myPassword1!",
|
||||
"FullName":"Test OrgAdmin",
|
||||
"EmailAddress":"test@admin.org"
|
||||
},
|
||||
"OrgVdc": {
|
||||
"Name":"TestOrgVdc",
|
||||
"FixedSize": "M",
|
||||
"CPULimit": "1000",
|
||||
"MEMLimit":"1000",
|
||||
"StorageLimit":"1000",
|
||||
"StorageProfile":"Standard-DC01",
|
||||
"ProviderVDC":"Provider-VDC-DC01",
|
||||
"NetworkPool":"Provider-VDC-DC01-NetPool",
|
||||
"ExternalNetwork": "External_OrgVdcNet",
|
||||
"EdgeGateway": "Yes",
|
||||
"IPAddress":"192.168.100.1",
|
||||
"SubnetMask":"255.255.255.0",
|
||||
"Gateway":"192.168.100.254",
|
||||
"IPRangeStart":"192.168.100.2",
|
||||
"IPRangeEnd":"192.168.100.3"
|
||||
}
|
||||
}
|
||||
|
||||
.NOTES
|
||||
File Name : Invoke-MyOnBoarding.ps1
|
||||
Author : Markus Kraus
|
||||
Version : 1.3
|
||||
State : Ready
|
||||
|
||||
.LINK
|
||||
https://mycloudrevolution.com/
|
||||
|
||||
.EXAMPLE
|
||||
Invoke-MyOnBoarding -ConfigFile ".\OnBoarding.json" -Enabled:$true
|
||||
|
||||
.EXAMPLE
|
||||
Invoke-MyOnBoarding -ConfigFile ".\OnBoarding.json" -Enabled:$false
|
||||
|
||||
.PARAMETER ConfigFile
|
||||
Full Path to the JSON Config File
|
||||
|
||||
.PARAMETER Enabled
|
||||
Should the Customer be enabled after creation
|
||||
|
||||
Default: $False
|
||||
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Full Path to the JSON Config File")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $ConfigFile,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Should the Customer be enabled after creation")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[Switch]$Enabled
|
||||
)
|
||||
Process {
|
||||
|
||||
$Valid = $true
|
||||
|
||||
Write-Verbose "## Import JSON Config"
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Importing JSON Config...`n"
|
||||
$Configs = Get-Content -Raw -Path $ConfigFile -ErrorAction Continue | ConvertFrom-Json -ErrorAction Continue
|
||||
|
||||
if (!($Configs)) {
|
||||
$Valid = $false
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Importing JSON Config Failed" -ForegroundColor Red
|
||||
}
|
||||
else {
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Importing JSON Config OK" -ForegroundColor Green
|
||||
}
|
||||
|
||||
if ($Valid) {
|
||||
try{
|
||||
Write-Verbose "## Create Org"
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Creating new Org...`n" -ForegroundColor Yellow
|
||||
$Trash = New-MyOrg -Name $Configs.Org.Name -FullName $Configs.Org.Fullname -Description $Configs.Org.Description -Enabled:$Enabled
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Creating new Org OK" -ForegroundColor Green
|
||||
Get-Org -Name $Configs.Org.Name | Select-Object Name, FullName, Enabled | Format-Table -AutoSize
|
||||
}
|
||||
catch {
|
||||
$Valid = $false
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Creating new Org Failed" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
|
||||
if ($Valid) {
|
||||
try{
|
||||
Write-Verbose "## Create OrgAdmin"
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Creating new OrgAdmin...`n" -ForegroundColor Yellow
|
||||
$Trash = New-MyOrgAdmin -Name $Configs.OrgAdmin.Name -Pasword $Configs.OrgAdmin.Pasword -FullName $Configs.OrgAdmin.FullName -EmailAddress $Configs.OrgAdmin.EmailAddress -Org $Configs.Org.Name -Enabled:$Enabled
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Creating new OrgAdmin OK" -ForegroundColor Green
|
||||
Get-CIUser -Org $Configs.Org.Name -Name $Configs.OrgAdmin.Name | Select-Object Name, FullName, Email | Format-Table -AutoSize
|
||||
}
|
||||
catch {
|
||||
$Valid = $false
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Creating new OrgAdmin Failed" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
if ($Valid) {
|
||||
try{
|
||||
Write-Verbose "## Create OrgVdc"
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Creating new OrgVdc...`n" -ForegroundColor Yellow
|
||||
|
||||
if ($Configs.OrgVdc.FixedSize){
|
||||
|
||||
Write-Host "Fixed Size (T-Shirt Size) '$($Configs.OrgVdc.FixedSize)' Org VDC Requested!"
|
||||
|
||||
switch ($Configs.OrgVdc.FixedSize) {
|
||||
M {
|
||||
[String]$CPULimit = 36000
|
||||
[String]$MEMLimit = 122880
|
||||
[String]$StorageLimit = 1048576
|
||||
}
|
||||
L {
|
||||
[String]$CPULimit = 36000
|
||||
[String]$MEMLimit = 245760
|
||||
[String]$StorageLimit = 1048576
|
||||
}
|
||||
default {throw "Invalid T-Shirt Size!"}
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
Write-Host "Custom Org VDC Size Requested!"
|
||||
|
||||
$CPULimit = $Configs.OrgVdc.CPULimit
|
||||
$MEMLimit = $Configs.OrgVdc.MEMLimit
|
||||
$StorageLimit = $Configs.OrgVdc.StorageLimit
|
||||
|
||||
}
|
||||
|
||||
if ($Configs.OrgVdc.ExternalNetwork -and $Configs.OrgVdc.EdgeGateway -like "Yes"){
|
||||
Write-Host "Edge Gateway for Org VDC '$($Configs.OrgVdc.Name)' Requested!"
|
||||
$Trash = New-MyOrgVdc -Name $Configs.OrgVdc.Name -CPULimit $CPULimit -MEMLimit $MEMLimit -StorageLimit $StorageLimit -Networkpool $Configs.OrgVdc.NetworkPool `
|
||||
-StorageProfile $Configs.OrgVdc.StorageProfile -ProviderVDC $Configs.OrgVdc.ProviderVDC -Org $Configs.Org.Name -Enabled:$Enabled
|
||||
|
||||
$EdgeName = $Configs.Org.Name + "-ESG01"
|
||||
$Trash = New-MyEdgeGateway -Name $EdgeName -OrgVDCName $Configs.OrgVdc.Name -Orgname $Configs.Org.Name -ExternalNetwork $Configs.OrgVdc.ExternalNetwork `
|
||||
-IPAddress $Configs.OrgVdc.IPAddress -SubnetMask $Configs.OrgVdc.SubnetMask -Gateway $Configs.OrgVdc.Gateway -IPRangeStart $Configs.OrgVdc.IPRangeStart -IPRangeEnd $Configs.OrgVdc.IPRangeEnd
|
||||
}
|
||||
elseif ($Configs.OrgVdc.ExternalNetwork -and $Configs.OrgVdc.EdgeGateway -like "No"){
|
||||
Write-Host "External Network for Org VDC '$($Configs.OrgVdc.Name)' Requested!"
|
||||
$Trash = New-MyOrgVdc -Name $Configs.OrgVdc.Name -CPULimit $CPULimit -MEMLimit $MEMLimit -StorageLimit $StorageLimit -Networkpool $Configs.OrgVdc.NetworkPool `
|
||||
-StorageProfile $Configs.OrgVdc.StorageProfile -ProviderVDC $Configs.OrgVdc.ProviderVDC -ExternalNetwork $Configs.OrgVdc.ExternalNetwork -Org $Configs.Org.Name -Enabled:$Enabled
|
||||
}
|
||||
else {
|
||||
Write-Host "No external Connection for Org VDC '$($Configs.OrgVdc.Name)' Requested!"
|
||||
$Trash = New-PecOrgVdc -Name $Configs.OrgVdc.Name -CPULimit $CPULimit -MEMLimit $MEMLimit -StorageLimit $StorageLimit -Networkpool $ProVdcNetworkPool.Name `
|
||||
-StorageProfile $Configs.OrgVdc.StorageProfile -ProviderVDC $Configs.OrgVdc.ProviderVDC -Org $Configs.Org.Name -Enabled:$Enabled
|
||||
}
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Creating new OrgVdc OK" -ForegroundColor Green
|
||||
Get-OrgVdc -Org $Configs.Org.Name -Name $Configs.OrgVdc.Name | Select-Object Name, Enabled, CpuAllocationGhz, MemoryLimitGB, StorageLimitGB, AllocationModel, ThinProvisioned, UseFastProvisioning, `
|
||||
@{N="StorageProfile";E={$_.ExtensionData.VdcStorageProfiles.VdcStorageProfile.Name}}, `
|
||||
@{N='VCpuInMhz';E={$_.ExtensionData.VCpuInMhz}} | Format-Table -AutoSize
|
||||
|
||||
if ($Configs.OrgVdc.EdgeGateway -like "Yes"){
|
||||
Search-Cloud -QueryType EdgeGateway -Name $EdgeName | Select Name, IsBusy, GatewayStatus, HaStatus | ft -AutoSize
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$Valid = $false
|
||||
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") Creating new OrgVdc Failed" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
161
Modules/VMware-vCD-Module/functions/New-MyEdgeGateway.psm1
Normal file
161
Modules/VMware-vCD-Module/functions/New-MyEdgeGateway.psm1
Normal file
@@ -0,0 +1,161 @@
|
||||
#Requires -Version 4
|
||||
#Requires -Modules VMware.VimAutomation.Cloud, @{ModuleName="VMware.VimAutomation.Cloud";ModuleVersion="6.3.0.0"}
|
||||
Function New-MyEdgeGateway {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a new Edge Gateway with Default Parameters
|
||||
|
||||
.DESCRIPTION
|
||||
Creates a new Edge Gateway with Default Parameters
|
||||
|
||||
Default Parameters are:
|
||||
* Size
|
||||
* HA State
|
||||
* DNS Relay
|
||||
|
||||
|
||||
.NOTES
|
||||
File Name : New-MyEdgeGateway.ps1
|
||||
Author : Markus Kraus
|
||||
Version : 1.0
|
||||
State : Ready
|
||||
|
||||
.LINK
|
||||
https://mycloudrevolution.com/
|
||||
|
||||
.EXAMPLE
|
||||
New-MyEdgeGateway -Name "TestEdge" -OrgVDCName "TestVDC" -OrgName "TestOrg" -ExternalNetwork "ExternalNetwork" -IPAddress "192.168.100.1" -SubnetMask "255.255.255.0" -Gateway "192.168.100.254" -IPRangeStart ""192.168.100.2" -IPRangeEnd ""192.168.100.3" -Verbose
|
||||
|
||||
.PARAMETER Name
|
||||
Name of the New Edge Gateway as String
|
||||
|
||||
.PARAMETER OrgVDCName
|
||||
OrgVDC where the new Edge Gateway should be created as string
|
||||
|
||||
.PARAMETER OrgName
|
||||
Org where the new Edge Gateway should be created as string
|
||||
|
||||
.PARAMETER ExternalNetwork
|
||||
External Network of the new Edge Gateway as String
|
||||
|
||||
.PARAMETER IPAddress
|
||||
IP Address of the New Edge Gateway as IP Address
|
||||
|
||||
.PARAMETER SubnetMask
|
||||
Subnet Mask of the New Edge Gateway as IP Address
|
||||
|
||||
.PARAMETER Gateway
|
||||
Gateway of the New Edge Gateway as IP Address
|
||||
|
||||
.PARAMETER IPRangeStart
|
||||
Sub Allocation IP Range Start of the New Edge Gateway as IP Address
|
||||
|
||||
.PARAMETER IPRangeEnd
|
||||
Sub Allocation IP Range End of the New Edge Gateway as IP Address
|
||||
|
||||
.PARAMETER Timeout
|
||||
Timeout for the Edge Gateway to get Ready
|
||||
|
||||
Default: 120s
|
||||
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Name of the New Edge Gateway as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Name,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="OrgVDC where the new Edge Gateway should be created as string")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $OrgVdcName,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Org where the new Edge Gateway should be created as string")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $OrgName,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="External Network of the New Edge Gateway as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $ExternalNetwork,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="IP Address of the New Edge Gateway as IP Address")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[IPAddress] $IPAddress,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Subnet Mask of the New Edge Gateway as IP Address")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[IPAddress] $SubnetMask,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Gateway of the New Edge Gateway as IP Address")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[IPAddress] $Gateway,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Sub Allocation IP Range Start the New Edge Gateway as IP Address")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[IPAddress] $IPRangeStart,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Sub Allocation IP Range End the New Edge Gateway as IP Address")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[IPAddress] $IPRangeEnd,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False,HelpMessage="Timeout for the Edge Gateway to get Ready")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[int] $Timeout = 120
|
||||
)
|
||||
Process {
|
||||
|
||||
## Get Org vDC
|
||||
Write-Verbose "Get Org vDC"
|
||||
[Array] $orgVdc = Get-Org -Name $OrgName | Get-OrgVdc -Name $OrgVdcName
|
||||
|
||||
if ( $orgVdc.Count -gt 1) {
|
||||
throw "Multiple OrgVdcs found!"
|
||||
}
|
||||
elseif ( $orgVdc.Count -lt 1) {
|
||||
throw "No OrgVdc found!"
|
||||
}
|
||||
## Get External Network
|
||||
Write-Verbose "Get External Network"
|
||||
$extNetwork = Get-ExternalNetwork | Get-CIView -Verbose:$False | Where-Object {$_.name -eq $ExternalNetwork}
|
||||
|
||||
## Build EdgeGatway Configuration
|
||||
Write-Verbose "Build EdgeGatway Configuration"
|
||||
$EdgeGateway = New-Object VMware.VimAutomation.Cloud.Views.Gateway
|
||||
$EdgeGateway.Name = $Name
|
||||
$EdgeGateway.Configuration = New-Object VMware.VimAutomation.Cloud.Views.GatewayConfiguration
|
||||
#$EdgeGateway.Configuration.BackwardCompatibilityMode = $false
|
||||
$EdgeGateway.Configuration.GatewayBackingConfig = "compact"
|
||||
$EdgeGateway.Configuration.UseDefaultRouteForDnsRelay = $false
|
||||
$EdgeGateway.Configuration.HaEnabled = $false
|
||||
|
||||
$EdgeGateway.Configuration.EdgeGatewayServiceConfiguration = New-Object VMware.VimAutomation.Cloud.Views.GatewayFeatures
|
||||
$EdgeGateway.Configuration.GatewayInterfaces = New-Object VMware.VimAutomation.Cloud.Views.GatewayInterfaces
|
||||
|
||||
$EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface = New-Object VMware.VimAutomation.Cloud.Views.GatewayInterface
|
||||
$EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[0].name = $extNetwork.Name
|
||||
$EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[0].DisplayName = $extNetwork.Name
|
||||
$EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[0].Network = $extNetwork.Href
|
||||
$EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[0].InterfaceType = "uplink"
|
||||
$EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[0].UseForDefaultRoute = $true
|
||||
$EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[0].ApplyRateLimit = $false
|
||||
|
||||
$ExNetexternalSubnet = New-Object VMware.VimAutomation.Cloud.Views.SubnetParticipation
|
||||
$ExNetexternalSubnet.Gateway = $Gateway.IPAddressToString
|
||||
$ExNetexternalSubnet.Netmask = $SubnetMask.IPAddressToString
|
||||
$ExNetexternalSubnet.IpAddress = $IPAddress.IPAddressToString
|
||||
$ExNetexternalSubnet.IpRanges = New-Object VMware.VimAutomation.Cloud.Views.IpRanges
|
||||
$ExNetexternalSubnet.IpRanges.IpRange = New-Object VMware.VimAutomation.Cloud.Views.IpRange
|
||||
$ExNetexternalSubnet.IpRanges.IpRange[0].StartAddress = $IPRangeStart.IPAddressToString
|
||||
$ExNetexternalSubnet.IpRanges.IpRange[0].EndAddress = $IPRangeEnd.IPAddressToString
|
||||
|
||||
$EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[0].SubnetParticipation = $ExNetexternalSubnet
|
||||
|
||||
## Create EdgeGatway
|
||||
Write-Verbose "Create EdgeGatway"
|
||||
$CreateEdgeGateway = $orgVdc.ExtensionData.CreateEdgeGateway($EdgeGateway)
|
||||
|
||||
## Wait for EdgeGatway to become Ready
|
||||
Write-Verbose "Wait for EdgeGatway to become Ready"
|
||||
while((Search-Cloud -QueryType EdgeGateway -Name $Name -Verbose:$False).IsBusy -eq $True){
|
||||
$i++
|
||||
Start-Sleep 5
|
||||
if($i -gt $Timeout) { Write-Error "Creating Edge Gateway."; break}
|
||||
Write-Progress -Activity "Creating Edge Gateway" -Status "Wait for Edge to become Ready..."
|
||||
}
|
||||
Write-Progress -Activity "Creating Edge Gateway" -Completed
|
||||
Start-Sleep 1
|
||||
|
||||
Search-Cloud -QueryType EdgeGateway -Name $Name | Select-Object Name, IsBusy, GatewayStatus, HaStatus | Format-Table -AutoSize
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
107
Modules/VMware-vCD-Module/functions/New-MyOrg.psm1
Normal file
107
Modules/VMware-vCD-Module/functions/New-MyOrg.psm1
Normal file
@@ -0,0 +1,107 @@
|
||||
#Requires -Version 4
|
||||
#Requires -Modules VMware.VimAutomation.Cloud, @{ModuleName="VMware.VimAutomation.Cloud";ModuleVersion="6.3.0.0"}
|
||||
Function New-MyOrg {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a new vCD Org with Default Parameters
|
||||
|
||||
.DESCRIPTION
|
||||
Creates a new vCD Org with Default Parameters.
|
||||
|
||||
Default Parameters are:
|
||||
* Catalog Publishing
|
||||
* Catalog Subscription
|
||||
* VM Quota
|
||||
* Stored VM Quota
|
||||
* VM Lease Time
|
||||
* Stored VM Lease Time
|
||||
* Password Policy Settings
|
||||
|
||||
.NOTES
|
||||
File Name : New-MyOrg.ps1
|
||||
Author : Markus Kraus
|
||||
Version : 1.1
|
||||
State : Ready
|
||||
|
||||
.LINK
|
||||
https://mycloudrevolution.com/
|
||||
|
||||
.EXAMPLE
|
||||
New-MyOrg -Name "TestOrg" -FullName "Test Org" -Description "PowerCLI Test Org"
|
||||
|
||||
.PARAMETER Name
|
||||
Name of the New Org as String
|
||||
|
||||
.PARAMETER FullName
|
||||
Full Name of the New Org as String
|
||||
|
||||
.PARAMETER Description
|
||||
Description of the New Org as String
|
||||
|
||||
.PARAMETER Enabled
|
||||
Should the New Org be enabled after creation
|
||||
|
||||
Default:$false
|
||||
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Name of the New Org as string")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Name,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Full Name of the New Org as string")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $FullName,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Description of the New Org as string")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Description,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Should the New Org be enabled after creation")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[Switch]$Enabled
|
||||
)
|
||||
Process {
|
||||
$vcloud = $DefaultCIServers[0].ExtensionData
|
||||
|
||||
## Create Objects
|
||||
$AdminOrg = New-Object VMware.VimAutomation.Cloud.Views.AdminOrg
|
||||
$orgGeneralSettings = New-Object VMware.VimAutomation.Cloud.Views.OrgGeneralSettings
|
||||
$orgOrgLeaseSettings = New-Object VMware.VimAutomation.Cloud.Views.OrgLeaseSettings
|
||||
$orgOrgVAppTemplateLeaseSettings = New-Object VMware.VimAutomation.Cloud.Views.OrgVAppTemplateLeaseSettings
|
||||
$orgOrgPasswordPolicySettings = New-Object VMware.VimAutomation.Cloud.Views.OrgPasswordPolicySettings
|
||||
$orgSettings = New-Object VMware.VimAutomation.Cloud.Views.OrgSettings
|
||||
|
||||
## Admin Settings
|
||||
$adminOrg.Name = $name
|
||||
$adminOrg.FullName = $FullName
|
||||
$adminOrg.Description = $description
|
||||
$adminOrg.IsEnabled = $Enabled
|
||||
|
||||
## Org Setting
|
||||
### General Org Settings
|
||||
$orgGeneralSettings.CanPublishCatalogs = $False
|
||||
$orgGeneralSettings.CanPublishExternally = $False
|
||||
$orgGeneralSettings.CanSubscribe = $True
|
||||
$orgGeneralSettings.DeployedVMQuota = 0
|
||||
$orgGeneralSettings.StoredVmQuota = 0
|
||||
$orgSettings.OrgGeneralSettings = $orgGeneralSettings
|
||||
### vApp Org Setting
|
||||
$orgOrgLeaseSettings.DeleteOnStorageLeaseExpiration = $false
|
||||
$orgOrgLeaseSettings.DeploymentLeaseSeconds = 0
|
||||
$orgOrgLeaseSettings.StorageLeaseSeconds = 0
|
||||
$orgSettings.VAppLeaseSettings = $orgOrgLeaseSettings
|
||||
### vApp Template Org Setting
|
||||
$orgOrgVAppTemplateLeaseSettings.DeleteOnStorageLeaseExpiration = $false
|
||||
$orgOrgVAppTemplateLeaseSettings.StorageLeaseSeconds = 0
|
||||
$orgSettings.VAppTemplateLeaseSettings = $orgOrgVAppTemplateLeaseSettings
|
||||
### PasswordPolicySettings Org Setting
|
||||
$orgOrgPasswordPolicySettings.AccountLockoutEnabled = $True
|
||||
$orgOrgPasswordPolicySettings.InvalidLoginsBeforeLockout = 5
|
||||
$orgOrgPasswordPolicySettings.AccountLockoutIntervalMinutes = 30
|
||||
$orgSettings.OrgPasswordPolicySettings = $orgOrgPasswordPolicySettings
|
||||
|
||||
$adminOrg.Settings = $orgSettings
|
||||
|
||||
$CreateOrg = $vcloud.CreateOrg($adminOrg)
|
||||
|
||||
Get-Org -Name $name | Format-Table -AutoSize
|
||||
}
|
||||
}
|
||||
91
Modules/VMware-vCD-Module/functions/New-MyOrgAdmin.psm1
Normal file
91
Modules/VMware-vCD-Module/functions/New-MyOrgAdmin.psm1
Normal file
@@ -0,0 +1,91 @@
|
||||
#Requires -Version 4
|
||||
#Requires -Modules VMware.VimAutomation.Cloud, @{ModuleName="VMware.VimAutomation.Cloud";ModuleVersion="6.3.0.0"}
|
||||
Function New-MyOrgAdmin {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a new vCD Org Admin with Default Parameters
|
||||
|
||||
.DESCRIPTION
|
||||
Creates a new vCD Org Admin with Default Parameters
|
||||
|
||||
Default Parameters are:
|
||||
* User Role
|
||||
|
||||
.NOTES
|
||||
File Name : New-MyOrgAdmin.ps1
|
||||
Author : Markus Kraus
|
||||
Version : 1.1
|
||||
State : Ready
|
||||
|
||||
.LINK
|
||||
https://mycloudrevolution.com/
|
||||
|
||||
.EXAMPLE
|
||||
New-MyOrgAdmin -Name "OrgAdmin" -Pasword "Anfang!!" -FullName "Org Admin" -EmailAddress "OrgAdmin@TestOrg.local" -Org "TestOrg"
|
||||
|
||||
.PARAMETER Name
|
||||
Name of the New Org Admin as String
|
||||
|
||||
.PARAMETER FullName
|
||||
Full Name of the New Org Admin as String
|
||||
|
||||
.PARAMETER Password
|
||||
Password of the New Org Admin as String
|
||||
|
||||
.PARAMETER EmailAddress
|
||||
EmailAddress of the New Org Admin as String
|
||||
|
||||
.PARAMETER Enabled
|
||||
Should the New Org be enabled after creation
|
||||
|
||||
Default:$false
|
||||
|
||||
.PARAMETER Org
|
||||
Org where the new Org Admin should be created as string
|
||||
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Name of the New Org Admin as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Name,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Password of the New Org Admin as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Pasword,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Full Name of the New Org Admin as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $FullName,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="EmailAddress of the New Org Admin as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $EmailAddress,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Org where the new Org Admin should be created as string")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Org,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Should the New Org be enabled after creation")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[Switch]$Enabled
|
||||
)
|
||||
Process {
|
||||
|
||||
## Create Objects
|
||||
$OrgED = (Get-Org $Org).ExtensionData
|
||||
$orgAdminUser = New-Object VMware.VimAutomation.Cloud.Views.User
|
||||
|
||||
## Settings
|
||||
$orgAdminUser.Name = $Name
|
||||
$orgAdminUser.FullName = $FullName
|
||||
$orgAdminUser.EmailAddress = $EmailAddress
|
||||
$orgAdminUser.Password = $Pasword
|
||||
$orgAdminUser.IsEnabled = $Enabled
|
||||
|
||||
$vcloud = $DefaultCIServers[0].ExtensionData
|
||||
|
||||
## Find Role
|
||||
$orgAdminRole = $vcloud.RoleReferences.RoleReference | Where-Object {$_.Name -eq "Organization Administrator"}
|
||||
$orgAdminUser.Role = $orgAdminRole
|
||||
|
||||
## Create User
|
||||
$user = $orgED.CreateUser($orgAdminUser)
|
||||
|
||||
Get-CIUser -Org $Org -Name $Name | Format-Table -AutoSize
|
||||
}
|
||||
}
|
||||
252
Modules/VMware-vCD-Module/functions/New-MyOrgVdc.psm1
Normal file
252
Modules/VMware-vCD-Module/functions/New-MyOrgVdc.psm1
Normal file
@@ -0,0 +1,252 @@
|
||||
#Requires -Version 4
|
||||
#Requires -Modules VMware.VimAutomation.Cloud, @{ModuleName="VMware.VimAutomation.Cloud";ModuleVersion="6.3.0.0"}
|
||||
Function New-MyOrgVdc {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a new vCD Org VDC with Default Parameters
|
||||
|
||||
.DESCRIPTION
|
||||
Creates a new vCD Org VDC with Default Parameters
|
||||
|
||||
Default Parameters are:
|
||||
* Allocation Model
|
||||
* Network Quota
|
||||
* VM Quota
|
||||
* 'vCpu In Mhz'
|
||||
* Fast Provisioning
|
||||
* Thin Provisioning
|
||||
* private Catalog
|
||||
|
||||
.NOTES
|
||||
File Name : New-MyOrgVdc.ps1
|
||||
Author : Markus Kraus
|
||||
Version : 1.2
|
||||
State : Ready
|
||||
|
||||
.LINK
|
||||
https://mycloudrevolution.com/
|
||||
|
||||
.EXAMPLE
|
||||
New-MyOrgVdc -Name "TestVdc" -CPULimit 1000 -MEMLimit 1000 -StorageLimit 1000 -StorageProfile "Standard-DC01" -NetworkPool "NetworkPool-DC01" -ProviderVDC "Provider-VDC-DC01" -Org "TestOrg" -ExternalNetwork "External_OrgVdcNet"
|
||||
|
||||
.EXAMPLE
|
||||
New-MyOrgVdc -Name "TestVdc" -CPULimit 1000 -MEMLimit 1000 -StorageLimit 1000 -StorageProfile "Standard-DC01" -NetworkPool "NetworkPool-DC01" -ProviderVDC "Provider-VDC-DC01" -Org "TestOrg"
|
||||
|
||||
.PARAMETER Name
|
||||
Name of the New Org VDC as String
|
||||
|
||||
.PARAMETER CPULimit
|
||||
CPU Limit (MHz) of the New Org VDC as String
|
||||
|
||||
.PARAMETER MEMLimit
|
||||
Memory Limit (MB) of the New Org VDC as String
|
||||
|
||||
.PARAMETER StorageLimit
|
||||
Storage Limit (MB) of the New Org VDC as String
|
||||
|
||||
.PARAMETER StorageProfile
|
||||
Storage Profile of the New Org VDC as String
|
||||
|
||||
.PARAMETER NetworkPool
|
||||
Network Pool of the New Org VDC as String
|
||||
|
||||
.PARAMETER ExternalNetwork
|
||||
Optional External Network of the New Org VDC as String
|
||||
|
||||
.PARAMETER Enabled
|
||||
Should the New Org VDC be enabled after creation
|
||||
|
||||
Default:$false
|
||||
|
||||
Note: If an External Network is requested the Org VDC will be enabled during External Network Configuration
|
||||
|
||||
.PARAMETER ProviderVDC
|
||||
ProviderVDC where the new Org VDC should be created as string
|
||||
|
||||
.PARAMETER Org
|
||||
Org where the new Org VDC should be created as string
|
||||
|
||||
.PARAMETER Timeout
|
||||
Timeout for the Org VDC to get Ready
|
||||
|
||||
Default: 120s
|
||||
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Name of the New Org VDC as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Name,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="CPU Limit (MHz) of the New Org VDC as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[int] $CPULimit,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Memory Limit (MB) of the New Org VDC as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[int] $MEMLimit,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Storage Limit (MB) of the New Org VDC as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[int] $StorageLimit,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Storage Profile of the New Org VDC as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $StorageProfile,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Network Pool of the New Org VDC as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $NetworkPool,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Optional External Network of the New Org VDC as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $ExternalNetwork,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Should the New Org VDC be enabled after creation")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[Switch]$Enabled,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="ProviderVDC where the new Org VDC should be created as string")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $ProviderVDC,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Org where the new Org VDC should be created as string")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Org,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False,HelpMessage="Timeout for the Org VDC to get Ready")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[int] $Timeout = 120
|
||||
)
|
||||
Process {
|
||||
## Create Objects and all Settings
|
||||
Write-Verbose "Create Objects and all Settings"
|
||||
$adminVdc = New-Object VMware.VimAutomation.Cloud.Views.AdminVdc
|
||||
$adminVdc.Name = $name
|
||||
$adminVdc.IsEnabled = $Enabled
|
||||
$OrgVdcproviderVdc = Get-ProviderVdc $ProviderVDC
|
||||
$providerVdcRef = New-Object VMware.VimAutomation.Cloud.Views.Reference
|
||||
$providerVdcRef.Href = $OrgVdcproviderVdc.Href
|
||||
$adminVdc.ProviderVdcReference = $providerVdcRef
|
||||
$adminVdc.AllocationModel = "AllocationPool"
|
||||
$adminVdc.ComputeCapacity = New-Object VMware.VimAutomation.Cloud.Views.ComputeCapacity
|
||||
$adminVdc.ComputeCapacity.Cpu = New-Object VMware.VimAutomation.Cloud.Views.CapacityWithUsage
|
||||
$adminVdc.ComputeCapacity.Cpu.Units = "MHz"
|
||||
$adminVdc.ComputeCapacity.Cpu.Limit = $CPULimit
|
||||
$adminVdc.ComputeCapacity.Cpu.Allocated = $CPULimit
|
||||
$adminVdc.ComputeCapacity.Memory = New-Object VMware.VimAutomation.Cloud.Views.CapacityWithUsage
|
||||
$adminVdc.ComputeCapacity.Memory.Units = "MB"
|
||||
$adminVdc.ComputeCapacity.Memory.Limit = $MEMLimit
|
||||
$adminVdc.ComputeCapacity.Memory.Allocated = $MEMLimit
|
||||
$adminVdc.StorageCapacity = New-Object VMware.VimAutomation.Cloud.Views.CapacityWithUsage
|
||||
$adminVdc.StorageCapacity.Units = "MB"
|
||||
$adminVdc.StorageCapacity.Limit = $StorageLimit
|
||||
$adminVdc.NetworkQuota = 10
|
||||
$adminVdc.VmQuota = 0
|
||||
$adminVdc.VCpuInMhz = 1000
|
||||
$adminVdc.VCpuInMhz2 = 1000
|
||||
$adminVdc.UsesFastProvisioning = $false
|
||||
$adminVdc.IsThinProvision = $true
|
||||
|
||||
## Create Org vDC
|
||||
Write-Verbose "Create Org vDC"
|
||||
$OrgED = (Get-Org $Org).ExtensionData
|
||||
$orgVdc = $orgED.CreateVdc($adminVdc)
|
||||
|
||||
## Wait for getting Ready
|
||||
Write-Verbose "Wait for getting Ready"
|
||||
$i = 0
|
||||
while(($orgVdc = Get-OrgVdc -Name $Name -Verbose:$false).Status -eq "NotReady"){
|
||||
$i++
|
||||
Start-Sleep 2
|
||||
if($i -gt $Timeout) { Write-Error "Creating Org Failed."; break}
|
||||
Write-Progress -Activity "Creating Org" -Status "Wait for Org to become Ready..."
|
||||
}
|
||||
Write-Progress -Activity "Creating Org" -Completed
|
||||
Start-Sleep 2
|
||||
|
||||
## Search given Storage Profile
|
||||
Write-Verbose "Search given Storage Profile"
|
||||
$ProVdcStorageProfile = search-cloud -QueryType ProviderVdcStorageProfile -Name $StorageProfile | Get-CIView
|
||||
|
||||
## Create Storage Profile Object with Settings
|
||||
Write-Verbose "Create Storage Profile Object with Settings"
|
||||
$spParams = new-object VMware.VimAutomation.Cloud.Views.VdcStorageProfileParams
|
||||
$spParams.Limit = $StorageLimit
|
||||
$spParams.Units = "MB"
|
||||
$spParams.ProviderVdcStorageProfile = $ProVdcStorageProfile.href
|
||||
$spParams.Enabled = $true
|
||||
$spParams.Default = $true
|
||||
$UpdateParams = new-object VMware.VimAutomation.Cloud.Views.UpdateVdcStorageProfiles
|
||||
$UpdateParams.AddStorageProfile = $spParams
|
||||
|
||||
## Update Org vDC
|
||||
$orgVdc = Get-OrgVdc -Name $name
|
||||
$orgVdc.ExtensionData.CreateVdcStorageProfile($UpdateParams)
|
||||
|
||||
## Wait for getting Ready
|
||||
Write-Verbose "Wait for getting Ready"
|
||||
while(($orgVdc = Get-OrgVdc -Name $name -Verbose:$false).Status -eq "NotReady"){
|
||||
$i++
|
||||
Start-Sleep 1
|
||||
if($i -gt $Timeout) { Write-Error "Update Org Failed."; break}
|
||||
Write-Progress -Activity "Updating Org" -Status "Wait for Org to become Ready..."
|
||||
}
|
||||
Write-Progress -Activity "Updating Org" -Completed
|
||||
Start-Sleep 1
|
||||
|
||||
## Search Any-StorageProfile
|
||||
Write-Verbose "Search Any-StorageProfile"
|
||||
$orgvDCAnyProfile = search-cloud -querytype AdminOrgVdcStorageProfile | Where-Object {($_.Name -match '\*') -and ($_.VdcName -eq $orgVdc.Name)} | Get-CIView
|
||||
|
||||
## Disable Any-StorageProfile
|
||||
Write-Verbose "Disable Any-StorageProfile"
|
||||
$orgvDCAnyProfile.Enabled = $False
|
||||
$return = $orgvDCAnyProfile.UpdateServerData()
|
||||
|
||||
## Remove Any-StorageProfile
|
||||
Write-Verbose "Remove Any-StorageProfile"
|
||||
$ProfileUpdateParams = new-object VMware.VimAutomation.Cloud.Views.UpdateVdcStorageProfiles
|
||||
$ProfileUpdateParams.RemoveStorageProfile = $orgvDCAnyProfile.href
|
||||
$remove = $orgvdc.extensiondata.CreatevDCStorageProfile($ProfileUpdateParams)
|
||||
|
||||
## Wait for getting Ready
|
||||
Write-Verbose "Wait for getting Ready"
|
||||
while(($orgVdc = Get-OrgVdc -Name $name -Verbose:$false).Status -eq "NotReady"){
|
||||
$i++
|
||||
Start-Sleep 1
|
||||
if($i -gt $Timeout) { Write-Error "Update Org Failed."; break}
|
||||
Write-Progress -Activity "Updating Org" -Status "Wait for Org to become Ready..."
|
||||
}
|
||||
Write-Progress -Activity "Updating Org" -Completed
|
||||
Start-Sleep 1
|
||||
|
||||
## Set NetworkPool for correct location
|
||||
Write-Verbose "Set NetworkPool for correct location"
|
||||
$orgVdc = Get-OrgVdc -Name $name
|
||||
$ProVdcNetworkPool = Get-NetworkPool -ProviderVdc $ProviderVDC -Name $NetworkPool
|
||||
$set = Set-OrgVdc -OrgVdc $orgVdc -NetworkPool $ProVdcNetworkPool -NetworkMaxCount "10"
|
||||
|
||||
## Create private Catalog
|
||||
Write-Verbose "Create private Catalog Object"
|
||||
$OrgCatalog = New-Object VMware.VimAutomation.Cloud.Views.AdminCatalog
|
||||
$OrgCatalog.name = "$Org Private Catalog"
|
||||
if (!(Get-Org $org | Get-Catalog -Name $OrgCatalog.name -ErrorAction SilentlyContinue)) {
|
||||
Write-Verbose "Create private Catalog"
|
||||
$CreateCatalog = (Get-Org $org | Get-CIView).CreateCatalog($OrgCatalog)
|
||||
$AccessControlRule = New-CIAccessControlRule -Entity $CreateCatalog.name -EveryoneInOrg -AccessLevel ReadWrite -Confirm:$False
|
||||
}
|
||||
else {
|
||||
Write-Output "Catalog '$($OrgCatalog.name)' aleady exists!"
|
||||
}
|
||||
|
||||
## Create a direct connect network
|
||||
if ($ExternalNetwork) {
|
||||
Write-Verbose "Create a direct connect network"
|
||||
Write-Output "Org VDC '$Name' needs to be enabled to add an external Network!"
|
||||
$EnableOrgVdc = Set-OrgVdc -OrgVdc $Name -Enabled:$True
|
||||
$orgVdcView = Get-OrgVdc $Name | Get-CIView
|
||||
$extNetwork = $_.externalnetwork
|
||||
$extNetwork = Get-ExternalNetwork | Get-CIView -Verbose:$false | Where-Object {$_.name -eq $ExternalNetwork}
|
||||
$orgNetwork = new-object vmware.vimautomation.cloud.views.orgvdcnetwork
|
||||
$orgNetwork.name = $ExternalNetwork
|
||||
$orgNetwork.Configuration = New-Object VMware.VimAutomation.Cloud.Views.NetworkConfiguration
|
||||
$orgNetwork.Configuration.FenceMode = 'bridged'
|
||||
$orgNetwork.configuration.ParentNetwork = New-Object vmware.vimautomation.cloud.views.reference
|
||||
$orgNetwork.configuration.ParentNetwork.href = $extNetwork.href
|
||||
|
||||
$result = $orgVdcView.CreateNetwork($orgNetwork)
|
||||
}
|
||||
|
||||
Get-OrgVdc -Name $name | Format-Table -AutoSize
|
||||
}
|
||||
}
|
||||
BIN
Modules/VMware-vCD-Module/media/Invoke-MyOnBoarding.png
Normal file
BIN
Modules/VMware-vCD-Module/media/Invoke-MyOnBoarding.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
BIN
Modules/VMware-vCD-Module/media/VSCode-Pester-Tests.png
Normal file
BIN
Modules/VMware-vCD-Module/media/VSCode-Pester-Tests.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
35
Modules/VMware-vCD-Module/tests/VMware-vCD-Module.Tests.ps1
Normal file
35
Modules/VMware-vCD-Module/tests/VMware-vCD-Module.Tests.ps1
Normal file
@@ -0,0 +1,35 @@
|
||||
$moduleRoot = Resolve-Path "$PSScriptRoot\.."
|
||||
$moduleName = "VMware-vCD-Module"
|
||||
$ConfigFile = "$moduleRoot\examples\OnBoarding.json"
|
||||
|
||||
Describe "General project validation: $moduleName" {
|
||||
|
||||
$scripts = Get-ChildItem $moduleRoot -Include *.ps1, *.psm1, *.psd1 -Recurse
|
||||
|
||||
# TestCases are splatted to the script so we need hashtables
|
||||
$testCase = $scripts | Foreach-Object {@{file = $_}}
|
||||
It "Script <file> should be valid powershell" -TestCases $testCase {
|
||||
param($file)
|
||||
|
||||
$file.fullname | Should Exist
|
||||
|
||||
$contents = Get-Content -Path $file.fullname -ErrorAction Stop
|
||||
$errors = $null
|
||||
$null = [System.Management.Automation.PSParser]::Tokenize($contents, [ref]$errors)
|
||||
$errors.Count | Should Be 0
|
||||
}
|
||||
|
||||
It "Module '$moduleName' prerequirements are met" {
|
||||
{Import-Module VMware.VimAutomation.Cloud -Force} | Should Not Throw
|
||||
}
|
||||
|
||||
It "Module '$moduleName' can import cleanly" {
|
||||
{Import-Module (Join-Path $moduleRoot "$moduleName.psd1") -force } | Should Not Throw
|
||||
}
|
||||
|
||||
It "Module '$moduleName' JSON example is valid" {
|
||||
{Get-Content -Raw -Path $ConfigFile | ConvertFrom-Json} | Should Not Throw
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
30
Modules/VMware-vCD-TenantReport/README.md
Normal file
30
Modules/VMware-vCD-TenantReport/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
VMware-vCD-TenantReport PowerShell Module
|
||||
=============
|
||||
|
||||
# About
|
||||
|
||||
## Project Owner:
|
||||
|
||||
Markus Kraus [@vMarkus_K](https://twitter.com/vMarkus_K)
|
||||
|
||||
MY CLOUD-(R)EVOLUTION [mycloudrevolution.com](http://mycloudrevolution.com/)
|
||||
|
||||
## Project WebSite:
|
||||
|
||||
[mycloudrevolution.com](http://mycloudrevolution.com/)
|
||||
|
||||
## Project Documentation:
|
||||
|
||||
[Read the Docs](http://readthedocs.io/)
|
||||
|
||||
## Project Description:
|
||||
|
||||
The 'VMware-vCD-TenantReport' PowerShell Module creates with the Fuction 'Get-VcdTenantReport' a HTML Report of your vCloud Director Objects.
|
||||
|
||||

|
||||
|
||||
Big thanks to [Timothy Dewin](https://twitter.com/tdewin) for his great [PowerStartHTML](https://github.com/tdewin/randomsamples/tree/master/powerstarthtml) PowerShell Module which is used to generate the Report for this Module.
|
||||
|
||||
|
||||
|
||||
|
||||
122
Modules/VMware-vCD-TenantReport/VMware-vCD-TenantReport.psd1
Normal file
122
Modules/VMware-vCD-TenantReport/VMware-vCD-TenantReport.psd1
Normal file
@@ -0,0 +1,122 @@
|
||||
#
|
||||
# Modulmanifest für das Modul "VMware-vCD-TenantReport"
|
||||
#
|
||||
# Generiert von: Markus Kraus
|
||||
#
|
||||
# Generiert am: 8/22/2017
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Die diesem Manifest zugeordnete Skript- oder Binärmoduldatei.
|
||||
# RootModule = 'VMware-vCD-TenantReport.psm1'
|
||||
|
||||
# Die Versionsnummer dieses Moduls
|
||||
ModuleVersion = '1.0.2'
|
||||
|
||||
# ID zur eindeutigen Kennzeichnung dieses Moduls
|
||||
GUID = '21a71eaa-d259-48c5-8482-643ba152af76'
|
||||
|
||||
# Autor dieses Moduls
|
||||
Author = 'Markus'
|
||||
|
||||
# Unternehmen oder Hersteller dieses Moduls
|
||||
CompanyName = 'mycloudrevolution.com'
|
||||
|
||||
# Urheberrechtserklärung für dieses Modul
|
||||
Copyright = '(c) 2017 Markus Kraus. Alle Rechte vorbehalten.'
|
||||
|
||||
# Beschreibung der von diesem Modul bereitgestellten Funktionen
|
||||
# Description = ''
|
||||
|
||||
# Die für dieses Modul mindestens erforderliche Version des Windows PowerShell-Moduls
|
||||
# PowerShellVersion = ''
|
||||
|
||||
# Der Name des für dieses Modul erforderlichen Windows PowerShell-Hosts
|
||||
# PowerShellHostName = ''
|
||||
|
||||
# Die für dieses Modul mindestens erforderliche Version des Windows PowerShell-Hosts
|
||||
# PowerShellHostVersion = ''
|
||||
|
||||
# Die für dieses Modul mindestens erforderliche Microsoft .NET Framework-Version
|
||||
# DotNetFrameworkVersion = ''
|
||||
|
||||
# Die für dieses Modul mindestens erforderliche Version der CLR (Common Language Runtime)
|
||||
# CLRVersion = ''
|
||||
|
||||
# Die für dieses Modul erforderliche Prozessorarchitektur ("Keine", "X86", "Amd64").
|
||||
# ProcessorArchitecture = ''
|
||||
|
||||
# Die Module, die vor dem Importieren dieses Moduls in die globale Umgebung geladen werden müssen
|
||||
# RequiredModules = @()
|
||||
|
||||
# Die Assemblys, die vor dem Importieren dieses Moduls geladen werden müssen
|
||||
# RequiredAssemblies = @()
|
||||
|
||||
# Die Skriptdateien (PS1-Dateien), die vor dem Importieren dieses Moduls in der Umgebung des Aufrufers ausgeführt werden.
|
||||
# ScriptsToProcess = @()
|
||||
|
||||
# Die Typdateien (.ps1xml), die beim Importieren dieses Moduls geladen werden sollen
|
||||
# TypesToProcess = @()
|
||||
|
||||
# Die Formatdateien (.ps1xml), die beim Importieren dieses Moduls geladen werden sollen
|
||||
# FormatsToProcess = @()
|
||||
|
||||
# Die Module, die als geschachtelte Module des in "RootModule/ModuleToProcess" angegebenen Moduls importiert werden sollen.
|
||||
NestedModules = @( "modules/PowerStartHTML/PowerStartHTML.psd1",
|
||||
"functions/Get-VcdTenantReport.psm1" )
|
||||
|
||||
# Aus diesem Modul zu exportierende Funktionen
|
||||
FunctionsToExport = '*'
|
||||
|
||||
# Aus diesem Modul zu exportierende Cmdlets
|
||||
CmdletsToExport = '*'
|
||||
|
||||
# Die aus diesem Modul zu exportierenden Variablen
|
||||
VariablesToExport = '*'
|
||||
|
||||
# Aus diesem Modul zu exportierende Aliase
|
||||
AliasesToExport = '*'
|
||||
|
||||
# Aus diesem Modul zu exportierende DSC-Ressourcen
|
||||
# DscResourcesToExport = @()
|
||||
|
||||
# Liste aller Module in diesem Modulpaket
|
||||
# ModuleList = @()
|
||||
|
||||
# Liste aller Dateien in diesem Modulpaket
|
||||
# FileList = @()
|
||||
|
||||
# Die privaten Daten, die an das in "RootModule/ModuleToProcess" angegebene Modul übergeben werden sollen. Diese können auch eine PSData-Hashtabelle mit zusätzlichen von PowerShell verwendeten Modulmetadaten enthalten.
|
||||
PrivateData = @{
|
||||
|
||||
PSData = @{
|
||||
|
||||
# 'Tags' wurde auf das Modul angewendet und unterstützt die Modulermittlung in Onlinekatalogen.
|
||||
# Tags = @()
|
||||
|
||||
# Eine URL zur Lizenz für dieses Modul.
|
||||
# LicenseUri = ''
|
||||
|
||||
# Eine URL zur Hauptwebsite für dieses Projekt.
|
||||
# ProjectUri = ''
|
||||
|
||||
# Eine URL zu einem Symbol, das das Modul darstellt.
|
||||
# IconUri = ''
|
||||
|
||||
# 'ReleaseNotes' des Moduls
|
||||
# ReleaseNotes = ''
|
||||
|
||||
} # Ende der PSData-Hashtabelle
|
||||
|
||||
} # Ende der PrivateData-Hashtabelle
|
||||
|
||||
# HelpInfo-URI dieses Moduls
|
||||
# HelpInfoURI = ''
|
||||
|
||||
# Standardpräfix für Befehle, die aus diesem Modul exportiert werden. Das Standardpräfix kann mit "Import-Module -Prefix" überschrieben werden.
|
||||
# DefaultCommandPrefix = ''
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
function Get-VcdTenantReport {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
1.0.0 - Inital Release
|
||||
1.0.1 - Removed "Test-IP" Module
|
||||
1.0.2 - More Detailed Console Log
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
Examle Usage of BOOTSTRAP with PowerShell
|
||||
https://github.com/tdewin/randomsamples/tree/master/powershell-veeamallstat
|
||||
BOOTSTRAP with PowerShell
|
||||
https://github.com/tdewin/randomsamples/tree/master/powerstarthtml
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vCD Version: 8.20
|
||||
PowerCLI Version: PowerCLI 6.5.1
|
||||
PowerShell Version: 5.0
|
||||
OS Version: Windows 8.1
|
||||
Keyword: VMware, vCD, Report, HTML
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function creates a HTML Report for your vCloud Director Organization.
|
||||
|
||||
This Function is fully tested as Organization Administrator.
|
||||
With lower permissions a unexpected behavior is possible.
|
||||
|
||||
.Example
|
||||
Get-VcdTenantReport -Server $ServerFQDN -Org $OrgName -Credential $MyCedential
|
||||
|
||||
.Example
|
||||
Get-VcdTenantReport -Server $ServerFQDN -Org $OrgName -Path "C:\Temp\Report.html"
|
||||
|
||||
.PARAMETER Server
|
||||
The FQDN of your vCloud Director Endpoint.
|
||||
|
||||
.PARAMETER Org
|
||||
The Organization Name.
|
||||
|
||||
.PARAMETER Credential
|
||||
PowerShell Credentials to access the Eénvironment.
|
||||
|
||||
.PARAMETER Path
|
||||
The Path of the exported HTML Report.
|
||||
|
||||
#>
|
||||
#Requires -Version 5
|
||||
#Requires -Modules VMware.VimAutomation.Cloud, @{ModuleName="VMware.VimAutomation.Cloud";ModuleVersion="6.5.1.0"}
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False)]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Server,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False)]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Org,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False)]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[PSCredential] $Credential,
|
||||
[Parameter(Mandatory=$false, ValueFromPipeline=$False)]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Path = ".\Report.html"
|
||||
|
||||
)
|
||||
|
||||
Process {
|
||||
|
||||
# Start Connection to vCD
|
||||
|
||||
if ($global:DefaultCIServers) {
|
||||
"$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Disconnect existing vCD Server ..."
|
||||
$Trash = Disconnect-CIServer -Server * -Force:$true -Confirm:$false -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
"$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Connect vCD Server ..."
|
||||
if ($Credential) {
|
||||
$Trash = Connect-CIServer -Server $Server -Org $Org -Credential $Credential -ErrorAction Stop
|
||||
}
|
||||
else {
|
||||
$Trash = Connect-CIServer -Server $Server -Org $Org -ErrorAction Stop
|
||||
}
|
||||
"$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Create HTML Report..."
|
||||
|
||||
# Init HTML Report
|
||||
$ps = New-PowerStartHTML -title "vCD Tenant Report"
|
||||
|
||||
#Set CSS Style
|
||||
$ps.cssStyles['.bgtitle'] = "background-color:grey"
|
||||
$ps.cssStyles['.bgsubsection'] = "background-color:#eee;"
|
||||
|
||||
# Processing Data
|
||||
## Get Main Objects
|
||||
[Array] $OrgVdcs = Get-OrgVdc
|
||||
[Array] $Catalogs = Get-Catalog
|
||||
[Array] $Users = Get-CIUser
|
||||
|
||||
## Add Header to Report
|
||||
$ps.Main().Add("div","jumbotron").N()
|
||||
$ps.Append("h1","display-3",("vCD Tenant Report" -f $OrgVdcs.Count)).Append("p","lead","Organization User Count: {0}" -f $Users.Count).Append("p","lead","Organization Catalog Count: {0}" -f $Catalogs.Count).Append("p","lead","Organization VDC Count: {0}" -f $OrgVdcs.Count).Append("hr","my-4").Append("p","font-italic","This Report lists the most important objects in your vCD Environmet. For more details contact your Service Provider").N()
|
||||
|
||||
## add Org Users to Report
|
||||
$ps.Main().Append("h2",$null,"Org Users").N()
|
||||
|
||||
$ps.Add('table','table').Add("tr","bgtitle text-white").Append("th",$null,"User Name").Append("th",$null,"Locked").Append("th",$null,"DeployedVMCount").Append("th",$null,"StoredVMCount").N()
|
||||
$ps.Add("tr").N()
|
||||
|
||||
foreach ($User in $Users) {
|
||||
$ps.Append("td",$null,$User.Name).N()
|
||||
$ps.Append("td",$null,$User.Locked).N()
|
||||
$ps.Append("td",$null,$User.DeployedVMCount).N()
|
||||
$ps.Append("td",$null,$User.StoredVMCount).N()
|
||||
$ps.Up().N()
|
||||
|
||||
}
|
||||
$ps.Up().N()
|
||||
|
||||
## add Org Catalogs to Report
|
||||
$ps.Main().Append("h2",$null,"Org Catalogs").N()
|
||||
|
||||
foreach ($Catalog in $Catalogs) {
|
||||
$ps.Add('table','table').Add("tr","bgtitle text-white").Append("th",$null,"Catalog Name").N()
|
||||
$ps.Add("tr").N()
|
||||
$ps.Append("td",$null,$Catalog.Name).Up().N()
|
||||
|
||||
$ps.Add("td","bgsubsection").N()
|
||||
$ps.Add("table","table bgcolorsub").N()
|
||||
$ps.Add("tr").N()
|
||||
|
||||
$headers = @("Item")
|
||||
foreach ($h in $headers) {
|
||||
$ps.Append("th",$null,$h).N()
|
||||
}
|
||||
$ps.Up().N()
|
||||
|
||||
### add Itens of the Catalog to the Report
|
||||
[Array] $Items = $Catalog.ExtensionData.CatalogItems.CatalogItem
|
||||
|
||||
foreach ($Item in $Items) {
|
||||
$ps.Add("tr").N()
|
||||
$ps.Append("td",$null,$Item.Name).N()
|
||||
|
||||
$ps.Up().N()
|
||||
|
||||
}
|
||||
|
||||
$ps.Up().Up().N()
|
||||
}
|
||||
$ps.Up().N()
|
||||
|
||||
## add Org VDC`s to the Report
|
||||
$ps.Main().Append("h2",$null,"Org VDCs").N()
|
||||
|
||||
foreach ($OrgVdc in $OrgVdcs) {
|
||||
$ps.Main().Add('table','table table-striped table-inverse').Add("tr").Append("th",$null,"VDC Name").Append("th",$null,"Enabled").Append("th",$null,"CpuUsedGHz").Append("th",$null,"MemoryUsedGB").Append("th",$null,"StorageUsedGB").Up().N()
|
||||
$ps.Add("tr").N()
|
||||
$ps.Append("td",$null,$OrgVdc.Name).Append("td",$null,$OrgVdc.Enabled).Append("td",$null,$OrgVdc.CpuUsedGHz).Append("td",$null,$OrgVdc.MemoryUsedGB).Append("td",$null,[Math]::Round($OrgVdc.StorageUsedGB,2)).Up().N()
|
||||
|
||||
### add Edge Gateways of this Org VDC to Report
|
||||
$ps.Main().Append("h3",$null,"Org VDC Edge Gateways").N()
|
||||
[Array] $Edges = Search-Cloud -QueryType EdgeGateway -Filter "Vdc==$($OrgVdc.Id)"
|
||||
|
||||
foreach ($Edge in $Edges) {
|
||||
$ps.Add('table','table').Add("tr","bgtitle text-white").Append("th",$null,"Edge Name").N()
|
||||
$ps.Add("tr").N()
|
||||
$ps.Append("td",$null,$Edge.Name).Up().N()
|
||||
|
||||
$ps.Add("td","bgsubsection").N()
|
||||
$ps.Add("table","table bgcolorsub").N()
|
||||
$ps.Append("tr").Append("td","font-weight-bold","HaStatus").Append("td",$null,($Edge.HaStatus)).N()
|
||||
$ps.Append("td","font-weight-bold","AdvancedNetworkingEnabled").Append("td",$null,$Edge.AdvancedNetworkingEnabled).N()
|
||||
$ps.Append("tr").Append("td","font-weight-bold","NumberOfExtNetworks").Append("td",$null,($Edge.NumberOfExtNetworks)).N()
|
||||
$ps.Append("td","font-weight-bold","NumberOfOrgNetworks").Append("td",$null,$Edge.NumberOfOrgNetworks).N()
|
||||
|
||||
$ps.Up().Up().N()
|
||||
}
|
||||
$ps.Up().N()
|
||||
|
||||
### add Org Networks of this Org VDC to Report
|
||||
$ps.Main().Append("h3",$null,"Org VDC Networks").N()
|
||||
[Array] $Networks = $OrgVdc | Get-OrgVdcNetwork
|
||||
|
||||
foreach ($Network in $Networks) {
|
||||
$ps.Add('table','table').Add("tr","bgtitle text-white").Append("th",$null,"Network Name").N()
|
||||
$ps.Add("tr").N()
|
||||
$ps.Append("td",$null,$Network.Name).Up().N()
|
||||
|
||||
$ps.Add("td","bgsubsection").N()
|
||||
$ps.Add("table","table bgcolorsub").N()
|
||||
$ps.Append("tr").Append("td","font-weight-bold","DefaultGateway").Append("td",$null,($Network.DefaultGateway)).N()
|
||||
$ps.Append("td","font-weight-bold","Netmask").Append("td",$null,$Network.Netmask).N()
|
||||
$ps.Append("tr").Append("td","font-weight-bold","NetworkType").Append("td",$null,($Network.NetworkType)).N()
|
||||
$ps.Append("td","font-weight-bold","StaticIPPool").Append("td",$null,$Network.StaticIPPool).N()
|
||||
|
||||
$ps.Up().Up().N()
|
||||
}
|
||||
$ps.Up().N()
|
||||
|
||||
### add vApps of this Org VDC to Report
|
||||
$ps.Main().Append("h3",$null,"Org VDC vApps").N()
|
||||
|
||||
[Array] $Vapps = $OrgVdc | Get-CIVApp
|
||||
|
||||
foreach ($Vapp in $Vapps) {
|
||||
$ps.Add('table','table').Add("tr","bgtitle text-white").Append("th",$null,"vApp Name").Append("th",$null,"Owner").Up().N()
|
||||
$ps.Add("tr").N()
|
||||
$ps.Append("td",$null,$Vapp.Name).Append("td",$null,$Vapp.Owner).Up().N()
|
||||
|
||||
#### add VMs of this vApp to Report
|
||||
$ps.Add("td","bgsubsection").N()
|
||||
$ps.Add("table","table bgcolorsub").N()
|
||||
$ps.Add("tr").N()
|
||||
|
||||
$headers = @("Name","Status","GuestOSFullName","CpuCount","MemoryGB")
|
||||
foreach ($h in $headers) {
|
||||
$ps.Append("th",$null,$h).N()
|
||||
}
|
||||
$ps.Up().N()
|
||||
|
||||
[Array] $VMs = $Vapp | Get-CIVM
|
||||
|
||||
foreach ($VM in $VMs) {
|
||||
$ps.Add("tr").N()
|
||||
$ps.Append("td",$null,$VM.Name).N()
|
||||
$ps.Append("td",$null,$VM.Status).N()
|
||||
$ps.Append("td",$null,$VM.GuestOSFullName).N()
|
||||
$ps.Append("td",$null,$VM.CpuCount).N()
|
||||
$ps.Append("td",$null,$VM.MemoryGB).N()
|
||||
|
||||
$ps.Up().N()
|
||||
|
||||
}
|
||||
$ps.Up().Up().N()
|
||||
|
||||
}
|
||||
$ps.Up().N()
|
||||
|
||||
}
|
||||
$ps.save($Path)
|
||||
|
||||
"$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Open HTML Report..."
|
||||
Start-Process $Path
|
||||
|
||||
}
|
||||
}
|
||||
BIN
Modules/VMware-vCD-TenantReport/media/Get-VcdTenantReport.png
Normal file
BIN
Modules/VMware-vCD-TenantReport/media/Get-VcdTenantReport.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
@@ -0,0 +1,237 @@
|
||||
class PowerStartHTML {
|
||||
[string]$PowerStartHtmlTemplate = "<html><head><meta charset=`"UTF-8`"/><title></title><style></style></head><body><div/></body></html>"
|
||||
[xml]$xmlDocument = $null
|
||||
$onLoadJS = $null
|
||||
$cssStyles= @{}
|
||||
$lastEl = $null
|
||||
$newEl = $null
|
||||
$indentedOutput = $false
|
||||
$bootstrapAtCompile = $false
|
||||
PowerStartHTML([string]$title) {
|
||||
$this.xmlDocument = $this.PowerStartHtmlTemplate
|
||||
$this.xmlDocument.html.head.title = $title
|
||||
$this.lastEl = $this.xmlDocument.html.body.ChildNodes[0]
|
||||
$this.onLoadJS = New-Object System.Collections.Generic.List[System.String]
|
||||
}
|
||||
[string] GetHtml() {
|
||||
$xmlclone = $this.xmlDocument.Clone()
|
||||
$csb = [System.Text.StringBuilder]::new()
|
||||
foreach ($cssStyle in $this.cssStyles.GetEnumerator()) {
|
||||
$null = $csb.AppendFormat("{0} {{ {1} }}",$cssStyle.Name,$cssStyle.Value)
|
||||
}
|
||||
$this.xmlDocument.html.head.style = $csb.toString()
|
||||
$this.AddBootStrapAtCompile()
|
||||
if($this.onLoadJS.Count -gt 0) {
|
||||
$this.onLoadJs.Insert(0,"`r`n`$(document).ready(function() {")
|
||||
$this.onLoadJs.Add("})`r`n")
|
||||
$el = $this.xmlDocument.CreateElement("script")
|
||||
$el.AppendChild($this.xmlDocument.CreateTextNode([System.String]::Join("`r`n",$this.onLoadJs)))
|
||||
$this.xmlDocument.html.body.AppendChild($el)
|
||||
}
|
||||
$ms = [System.IO.MemoryStream]::new()
|
||||
$xmlWriter = [System.Xml.XmlTextWriter]::new($ms,[System.Text.Encoding]::UTF8)
|
||||
if($this.indentedOutput) {
|
||||
$xmlWriter.Formatting = [System.Xml.Formatting]::Indented
|
||||
}
|
||||
$this.xmlDocument.WriteContentTo($xmlWriter)
|
||||
$xmlWriter.Flush()
|
||||
$ms.Flush()
|
||||
#make sure that everytime we do gethtml we keep it clean
|
||||
$this.xmlDocument = $xmlclone
|
||||
$ms.Position = 0;
|
||||
$sr = [System.IO.StreamReader]::new($ms);
|
||||
return ("<!DOCTYPE html>{0}`r`n" -f $sr.ReadToEnd())
|
||||
}
|
||||
Save($path) {
|
||||
$this.GetHtml() | Set-Content -path $path -Encoding UTF8
|
||||
}
|
||||
|
||||
AddAttr($el,$name,$value) {
|
||||
$attr = $this.xmlDocument.CreateAttribute($name)
|
||||
$attr.Value = $value
|
||||
$el.Attributes.Append($attr)
|
||||
}
|
||||
|
||||
AddAttrs($el,$dict) {
|
||||
foreach($a in $dict.GetEnumerator()) {
|
||||
$this.AddAttr($el,$a.Name,$a.Value)
|
||||
}
|
||||
}
|
||||
[PowerStartHTML] AddBootStrap() {
|
||||
$this.bootstrapAtCompile = $true
|
||||
return $this
|
||||
}
|
||||
AddJSScript($href,$integrity) {
|
||||
$el = $this.xmlDocument.CreateElement("script")
|
||||
$attrs = @{
|
||||
"src"="$href";
|
||||
"integrity"="$integrity";
|
||||
"crossorigin"="anonymous"
|
||||
}
|
||||
$this.AddAttrs($el,$attrs)
|
||||
$el.AppendChild($this.xmlDocument.CreateTextNode(""))
|
||||
$this.xmlDocument.html.body.AppendChild($el)
|
||||
}
|
||||
AddBootStrapAtCompile() { #Bootstrap script needs to be added at the end
|
||||
if($this.bootstrapAtCompile) {
|
||||
$el = $this.xmlDocument.CreateElement("link")
|
||||
$attrs = @{
|
||||
"rel"="stylesheet";
|
||||
"href"='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css';
|
||||
"integrity"="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M";
|
||||
"crossorigin"="anonymous"
|
||||
}
|
||||
$this.AddAttrs($el,$attrs)
|
||||
$el.AppendChild($this.xmlDocument.CreateTextNode(""))
|
||||
$this.xmlDocument.html.head.AppendChild($el)
|
||||
$this.AddJSScript('https://code.jquery.com/jquery-3.2.1.slim.min.js',"sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN")
|
||||
$this.AddJSScript('https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js',"sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4")
|
||||
$this.AddJSScript('https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js',"sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1")
|
||||
}
|
||||
}
|
||||
[PowerStartHTML] AddContainerAttrToMain() {
|
||||
$this.AddAttr($this.xmlDocument.html.body.ChildNodes[0],"class","container")
|
||||
return $this
|
||||
}
|
||||
[PowerStartHTML] Append($elType = "table",$className=$null,[string]$text=$null) {
|
||||
$el = $this.xmlDocument.CreateElement($elType)
|
||||
if($text -ne $null) {
|
||||
$el.AppendChild($this.xmlDocument.CreateTextNode($text))
|
||||
}
|
||||
if($className -ne $null) {
|
||||
$this.AddAttr($el,"class",$className)
|
||||
}
|
||||
$this.lastEl.AppendChild($el)
|
||||
$this.newEl = $el
|
||||
|
||||
return $this
|
||||
}
|
||||
[PowerStartHTML] Append($elType = "table",$className=$null) { return $this.Append($elType,$className,$null) }
|
||||
[PowerStartHTML] Append($elType = "table") { return $this.Append($elType,$null,$null) }
|
||||
[PowerStartHTML] Add($elType = "table",$className=$null,[string]$text=$null) {
|
||||
$this.Append($elType,$className,$text)
|
||||
$this.lastEl = $this.newEl
|
||||
return $this
|
||||
}
|
||||
[PowerStartHTML] Add($elType = "table",$className=$null) { return $this.Add($elType,$className,$null) }
|
||||
[PowerStartHTML] Add($elType = "table") { return $this.Add($elType,$null,$null) }
|
||||
[PowerStartHTML] Main() {
|
||||
$this.lastEl = $this.xmlDocument.html.body.ChildNodes[0];
|
||||
return $this
|
||||
}
|
||||
[PowerStartHTML] Up() {
|
||||
$this.lastEl = $this.lastEl.ParentNode;
|
||||
return $this
|
||||
}
|
||||
N() {}
|
||||
}
|
||||
class PowerStartHTMLPassThroughLine {
|
||||
$object;$cells
|
||||
PowerStartHTMLPassThroughLine($object) {
|
||||
$this.object = $object;
|
||||
$this.cells = new-object System.Collections.HashTable;
|
||||
}
|
||||
}
|
||||
class PowerStartHTMLPassThroughElement {
|
||||
$name;$text;$element;$id
|
||||
PowerStartHTMLPassThroughElement($name,$text,$element,$id) {
|
||||
$this.name = $name; $this.text = $text; $this.element = $element;$this.id = $id
|
||||
}
|
||||
}
|
||||
function New-PowerStartHTML {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$title,
|
||||
[switch]$nobootstrap=$false
|
||||
)
|
||||
$pshtml = (new-object PowerStartHTML($title))
|
||||
if(-not $nobootstrap) {
|
||||
$pshtml.AddBootStrap().AddContainerAttrToMain().N()
|
||||
}
|
||||
return $pshtml
|
||||
}
|
||||
function Add-PowerStartHTMLTable {
|
||||
param(
|
||||
[Parameter(Mandatory=$True,ValueFromPipeline=$True)]$object,
|
||||
[PowerStartHTML]$psHtml,
|
||||
[string]$tableTitle = $null,
|
||||
[string]$tableClass = $null,
|
||||
[string]$idOverride = $(if($tableTitle -ne $null) {($tableTitle.toLower() -replace "[^a-z0-9]","-") }),
|
||||
[switch]$passthroughTable = $false,
|
||||
[switch]$noheaders = $false
|
||||
)
|
||||
begin {
|
||||
if($tableTitle -ne $null) {
|
||||
$psHtml.Main().Append("h1",$null,$tableTitle).N()
|
||||
if($idOverride -ne $null) {
|
||||
$psHtml.AddAttr($psHtml.newEl,"id","header-$idOverride")
|
||||
}
|
||||
}
|
||||
$psHtml.Main().Add("table").N()
|
||||
[int]$r = 0
|
||||
[int]$c = 0
|
||||
if($idOverride -ne $null) {
|
||||
$psHtml.AddAttr($psHtml.newEl,"id","table-$idOverride")
|
||||
}
|
||||
if($tableClass -ne $null) {
|
||||
$psHtml.AddAttr($psHtml.newEl,"class",$tableClass)
|
||||
}
|
||||
[bool]$isFirst = $true
|
||||
}
|
||||
process {
|
||||
$c = 0
|
||||
|
||||
$props = $object | Get-Member -Type Properties
|
||||
if(-not $noheaders -and $isFirst) {
|
||||
$psHtml.Add("tr").N()
|
||||
if($idOverride -ne $null) {
|
||||
$psHtml.AddAttr($psHtml.newEl,"id","table-$idOverride-trh")
|
||||
}
|
||||
$props | % {
|
||||
$n = $_.Name;
|
||||
$psHtml.Append("th",$null,$n).N()
|
||||
if($idOverride -ne $null) {
|
||||
$cellid = "table-$idOverride-td-$r-$c"
|
||||
$psHtml.AddAttr($psHtml.newEl,"id",$cellid)
|
||||
}
|
||||
$c++
|
||||
}
|
||||
$c = 0
|
||||
$psHtml.Up().N()
|
||||
}
|
||||
|
||||
$psHtml.Add("tr").N()
|
||||
if($idOverride -ne $null) {
|
||||
$psHtml.AddAttr($psHtml.newEl,"id","table-$idOverride-tr-$r")
|
||||
}
|
||||
$pstableln = [PowerStartHTMLPassThroughLine]::new($object)
|
||||
|
||||
$props | % {
|
||||
$n = $_.Name;
|
||||
$psHtml.Append("td",$null,$object."$n").N()
|
||||
$cellid = $null
|
||||
if($idOverride -ne $null) {
|
||||
$cellid = "table-$idOverride-td-$r-$c"
|
||||
$psHtml.AddAttr($psHtml.newEl,"id",$cellid)
|
||||
}
|
||||
if($passthroughTable) {
|
||||
$pstableln.cells.Add($n,[PowerStartHTMLPassThroughElement]::new($n,($object."$n"),$psHtml.newEl,$cellid))
|
||||
}
|
||||
|
||||
$c++
|
||||
}
|
||||
if($passthroughTable) {
|
||||
$pstableln
|
||||
}
|
||||
$psHtml.Up().N()
|
||||
$isFirst = $false
|
||||
$r++
|
||||
}
|
||||
end {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Export-ModuleMember -Function @('New-PowerStartHTML','Add-PowerStartHTMLTable')
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
$moduleRoot = Resolve-Path "$PSScriptRoot\.."
|
||||
$moduleName = "VMware-vCD-TenantReport"
|
||||
|
||||
Describe "General project validation: $moduleName" {
|
||||
|
||||
$scripts = Get-ChildItem $moduleRoot -Include *.ps1, *.psm1, *.psd1 -Recurse
|
||||
|
||||
# TestCases are splatted to the script so we need hashtables
|
||||
$testCase = $scripts | Foreach-Object {@{file = $_}}
|
||||
It "Script <file> should be valid powershell" -TestCases $testCase {
|
||||
param($file)
|
||||
|
||||
$file.fullname | Should Exist
|
||||
|
||||
$contents = Get-Content -Path $file.fullname -ErrorAction Stop
|
||||
$errors = $null
|
||||
$null = [System.Management.Automation.PSParser]::Tokenize($contents, [ref]$errors)
|
||||
$errors.Count | Should Be 0
|
||||
}
|
||||
|
||||
It "Module '$moduleName' can import cleanly" {
|
||||
{Import-Module (Join-Path $moduleRoot "$moduleName.psd1") -force } | Should Not Throw
|
||||
}
|
||||
}
|
||||
18
Modules/VMware.Hosted/VMware.Hosted.psd1
Normal file
18
Modules/VMware.Hosted/VMware.Hosted.psd1
Normal file
@@ -0,0 +1,18 @@
|
||||
@{
|
||||
ModuleToProcess = 'VMware.Hosted.psm1'
|
||||
ModuleVersion = '1.0.0.0'
|
||||
GUID = '11393D09-D6B8-4E79-B9BC-247F1BE66683'
|
||||
Author = 'William Lam'
|
||||
CompanyName = 'primp-industries.com'
|
||||
Copyright = '(c) 2017. All rights reserved.'
|
||||
Description = 'Powershell Module for VMware Fusion 10 REST API'
|
||||
PowerShellVersion = '5.0'
|
||||
FunctionsToExport = 'Get-HostedCommand','Connect-HostedServer','Disconnect-HostedServer','Get-HostedVM','Start-HostedVM','Stop-HostedVM','Suspend-HostedVM','Resume-HostedVM','New-HostedVM','Remove-HostedVM','Get-HostedVMSharedFolder','New-HostedVMSharedFolder','Remove-HostedVMSharedFolder','Get-HostedVMNic','Get-HostedNetworks'
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
Tags = @('Fusion','REST','vmrest')
|
||||
LicenseUri = 'https://www.tldrlegal.com/l/mit'
|
||||
ProjectUri = 'https://github.com/lamw/PowerCLI-Example-Scripts/tree/master/Modules/VMware.Hosted'
|
||||
}
|
||||
}
|
||||
}
|
||||
501
Modules/VMware.Hosted/VMware.Hosted.psm1
Normal file
501
Modules/VMware.Hosted/VMware.Hosted.psm1
Normal file
@@ -0,0 +1,501 @@
|
||||
Function Get-Confirmation {
|
||||
$choice = ""
|
||||
while ($choice -notmatch "[y|n]"){
|
||||
$choice = read-host "Do you want to continue? (Y/N)"
|
||||
}
|
||||
if($choice -ne 'y') {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Function Connect-HostedServer {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Server,
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Username,
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Password,
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Protocol = "http",
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][int]$Port = 8697
|
||||
)
|
||||
$pair = $Username+":"+$Password
|
||||
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
|
||||
$base64 = [System.Convert]::ToBase64String($bytes)
|
||||
$basicAuthValue = "Basic $base64"
|
||||
$headers = @{Authorization = $basicAuthValue}
|
||||
|
||||
$Global:DefaultHostedServer = [pscustomobject] @{
|
||||
Server=$Protocol + "://" + $server + ":$Port/api";
|
||||
Protcol=$Protocol
|
||||
Headers=$headers
|
||||
}
|
||||
|
||||
if($DefaultHostedServer.Protcol -eq "https") {
|
||||
# PowerShell Core has a nice -SkipCertificateCheck but looks like Windows does NOT :(
|
||||
if($PSVersionTable.PSEdition -eq "Core") {
|
||||
$Global:fusionCommand = "Invoke-Webrequest -SkipCertificateCheck "
|
||||
} else {
|
||||
# Needed for Windows PowerShell to handle HTTPS scenario
|
||||
# https://stackoverflow.com/a/15627483
|
||||
$Provider = New-Object Microsoft.CSharp.CSharpCodeProvider
|
||||
$Compiler = $Provider.CreateCompiler()
|
||||
$Params = New-Object System.CodeDom.Compiler.CompilerParameters
|
||||
$Params.GenerateExecutable = $false
|
||||
$Params.GenerateInMemory = $true
|
||||
$Params.IncludeDebugInformation = $false
|
||||
$Params.ReferencedAssemblies.Add("System.DLL") > $null
|
||||
$TASource=@'
|
||||
namespace Local.ToolkitExtensions.Net.CertificatePolicy
|
||||
{
|
||||
public class TrustAll : System.Net.ICertificatePolicy
|
||||
{
|
||||
public bool CheckValidationResult(System.Net.ServicePoint sp,System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Net.WebRequest req, int problem)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
'@
|
||||
$TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
|
||||
$TAAssembly=$TAResults.CompiledAssembly
|
||||
## We create an instance of TrustAll and attach it to the ServicePointManager
|
||||
$TrustAll = $TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
|
||||
[System.Net.ServicePointManager]::CertificatePolicy = $TrustAll
|
||||
$Global:fusionCommand = "Invoke-Webrequest "
|
||||
}
|
||||
} else {
|
||||
$Global:fusionCommand = "Invoke-Webrequest "
|
||||
}
|
||||
$Global:DefaultHostedServer
|
||||
}
|
||||
|
||||
Function Disconnect-HostedServer {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Server
|
||||
)
|
||||
|
||||
$Global:DefaultHostedServer = $null
|
||||
}
|
||||
|
||||
Function Get-HostedVM {
|
||||
Param (
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
|
||||
)
|
||||
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
if($Id) {
|
||||
$vmUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id
|
||||
try {
|
||||
$params = "-Headers `$Global:DefaultHostedServer.Headers -Uri $vmUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vm = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
||||
break
|
||||
}
|
||||
|
||||
$vmIPUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/ip"
|
||||
try {
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmIPUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vmIPResults = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
$vmIP = $vmIPResults.ip
|
||||
} catch {
|
||||
$vmIP = "N/A"
|
||||
}
|
||||
|
||||
$vmPowerUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/power"
|
||||
try {
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vmPower = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
$vmPower = "N/A"
|
||||
}
|
||||
|
||||
$results = [pscustomobject] @{
|
||||
Id = $vm.Id;
|
||||
CPU = $vm.Cpu.processors;
|
||||
Memory = $vm.Memory;
|
||||
PowerState = $vmPower.power_state;
|
||||
IPAddress = $vmIP;
|
||||
}
|
||||
$results
|
||||
} else {
|
||||
$uri = $Global:DefaultHostedServer.Server + "/vms"
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $uri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
try {
|
||||
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Failed to list VMs"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Start-HostedVM {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id
|
||||
)
|
||||
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
$vmPowerUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/power"
|
||||
try {
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vmPower = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
||||
break
|
||||
}
|
||||
|
||||
if($vmPower.power_state -eq "poweredOff" -or $vmPower.power_state -eq "suspended") {
|
||||
try {
|
||||
Write-Host "Powering on VM $Id ..."
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method PUT -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `"on`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vm = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Unable to Power On VM $Id"
|
||||
break
|
||||
}
|
||||
} else {
|
||||
Write-Host "VM $Id is already Powered On"
|
||||
}
|
||||
}
|
||||
|
||||
Function Stop-HostedVM {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id,
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][boolean]$Soft,
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][boolean]$Confirm = $true
|
||||
)
|
||||
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
if($Confirm) {
|
||||
Get-Confirmation
|
||||
}
|
||||
|
||||
$vmPowerUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/power"
|
||||
try {
|
||||
$params += "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vmPower = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
||||
break
|
||||
}
|
||||
|
||||
if($vmPower.power_state -eq "poweredOn") {
|
||||
if($Soft) {
|
||||
try {
|
||||
Write-Host "Shutting down VM $Id ..."
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method PUT -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `"shutdown`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vm = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Unable to Shutdown VM $Id"
|
||||
break
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
Write-Host "Powering off VM $Id ..."
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method PUT -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `"off`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vm = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Unable to Power Off VM $Id"
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Host "VM $Id is already Powered Off"
|
||||
}
|
||||
}
|
||||
|
||||
Function Suspend-HostedVM {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id,
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][boolean]$Confirm
|
||||
)
|
||||
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
if($Confirm) {
|
||||
Get-Confirmation
|
||||
}
|
||||
|
||||
$vmPowerUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/power"
|
||||
try {
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vmPower = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
||||
break
|
||||
}
|
||||
|
||||
if($vmPower.power_state -eq "poweredOn") {
|
||||
try {
|
||||
Write-Host "Suspending VM $Id ..."
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method PUT -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `"suspend`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vm = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Unable to suspend VM $Id"
|
||||
break
|
||||
}
|
||||
} else {
|
||||
Write-Host "VM $Id can not be suspended because it is either Powered Off or Suspended"
|
||||
}
|
||||
}
|
||||
|
||||
Function Resume-HostedVM {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id
|
||||
)
|
||||
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
$vmPowerUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/power"
|
||||
try {
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vmPower = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
||||
break
|
||||
}
|
||||
|
||||
if($vmPower.power_state -eq "suspended") {
|
||||
try {
|
||||
Start-HostedVM -Id $Id
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Unable to Resume VM $Id"
|
||||
break
|
||||
}
|
||||
} else {
|
||||
Write-Host "VM $Id is not Suspended"
|
||||
}
|
||||
}
|
||||
|
||||
Function New-HostedVM {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$ParentId,
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Name
|
||||
)
|
||||
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
$vm = Get-HostedVM -Id $ParentId
|
||||
|
||||
if($vm -match "Invalid VM Id") {
|
||||
Write-host -ForegroundColor Red "Unable to find existing VM Id $ParentId"
|
||||
break
|
||||
}
|
||||
|
||||
$vmUri = $Global:DefaultHostedServer.Server + "/vms"
|
||||
$body = @{"ParentId"="$ParentId";"Name"=$Name}
|
||||
$body = $body | ConvertTo-Json
|
||||
|
||||
try {
|
||||
Write-Host "Cloning VM $ParentId to $Name ..."
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmUri -Method POST -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `$body"
|
||||
$command = $Global:fusionCommand + $params
|
||||
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Failed to Clone VM Id $ParentId"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Function Remove-HostedVM {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id,
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][boolean]$Confirm = $true
|
||||
)
|
||||
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
$vm = Get-HostedVM -Id $Id
|
||||
|
||||
if($vm -match "Invalid VM Id") {
|
||||
Write-host -ForegroundColor Red "Unable to find existing VM Id $Id"
|
||||
break
|
||||
}
|
||||
|
||||
if($Confirm) {
|
||||
Get-Confirmation
|
||||
}
|
||||
|
||||
$vmUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id
|
||||
try {
|
||||
Write-Host "Deleting VM Id $Id ..."
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmUri -Method DELETE -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Failed to Delete VM Id $Id"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-HostedVMSharedFolder {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id
|
||||
)
|
||||
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
$folderUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/sharedfolders"
|
||||
try {
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $folderUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Function New-HostedVMSharedFolder {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id,
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$FolderName,
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$HostPath
|
||||
)
|
||||
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
$body = @{"folder_id"="$FolderName";"host_path"=$HostPath;"flags"=4}
|
||||
$body = $body | ConvertTo-Json
|
||||
|
||||
$folderUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/sharedfolders"
|
||||
try {
|
||||
Write-Host "Creating new Shared Folder $FolderName to $HostPath for VM Id $Id ..."
|
||||
$params += "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $folderUri -Method POST -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `$body"
|
||||
$command = $Global:fusionCommand + $params
|
||||
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Failed to create Shared Folder for VM Id $Id"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Function Remove-HostedVMSharedFolder {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id,
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$FolderName,
|
||||
[parameter(Mandatory=$false,ValueFromPipeline=$true)][boolean]$Confirm = $true
|
||||
)
|
||||
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
if($Confirm) {
|
||||
Get-Confirmation
|
||||
}
|
||||
|
||||
$folderUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/sharedfolders/" + $FolderName
|
||||
try {
|
||||
Write-Host "Removing Shared Folder $FolderName for VM Id $Id ..."
|
||||
$params += "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $folderUri -Method DELETE -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Failed to remove Shared Folder for VM Id $Id"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-HostedVMNic {
|
||||
Param (
|
||||
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id
|
||||
)
|
||||
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
$vmNicUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/nic"
|
||||
try {
|
||||
$params += "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmNicUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$vmNics = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
||||
break
|
||||
}
|
||||
|
||||
$results = @()
|
||||
foreach ($vmNic in $vmNics.nics) {
|
||||
$tmp = [pscustomobject] @{
|
||||
Index = $vmNic.index;
|
||||
Type = $vmNic.Type;
|
||||
VMnet = $vmNic.Vmnet;
|
||||
}
|
||||
$results+=$tmp
|
||||
}
|
||||
$results
|
||||
}
|
||||
|
||||
Function Get-HostedNetworks {
|
||||
if(!$Global:DefaultHostedServer) {
|
||||
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
||||
exit
|
||||
}
|
||||
|
||||
$networksUri = $Global:DefaultHostedServer.Server + "/vmnet"
|
||||
try {
|
||||
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $networksUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
||||
$command = $Global:fusionCommand + $params
|
||||
$networks = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red "Unable to retrieve Networks"
|
||||
break
|
||||
}
|
||||
|
||||
$results = @()
|
||||
foreach ($network in $networks.vmnets) {
|
||||
$tmp = [pscustomobject] @{
|
||||
Name = $network.Name;
|
||||
Type = $network.Type;
|
||||
DHCP = $network.Dhcp;
|
||||
Network = $network.subnet;
|
||||
Netmask = $network.mask;
|
||||
}
|
||||
$results+=$tmp
|
||||
}
|
||||
$results
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"Type": "AUTOMATED",
|
||||
"Data": {
|
||||
"Name": "ICFarmJson",
|
||||
"DisplayName": "FarmJsonTest",
|
||||
"AccessGroup": "Root",
|
||||
"Description": "created IC Farm from PS via JSON",
|
||||
"Enabled": null,
|
||||
"Deleting": false,
|
||||
"Settings": {
|
||||
"DisconnectedSessionTimeoutPolicy" : "NEVER",
|
||||
"DisconnectedSessionTimeoutMinutes" : 1,
|
||||
"EmptySessionTimeoutPolicy" : "AFTER",
|
||||
"EmptySessionTimeoutMinutes" : 1,
|
||||
"LogoffAfterTimeout" : false
|
||||
},
|
||||
"Desktop": null,
|
||||
"DisplayProtocolSettings": {
|
||||
"DefaultDisplayProtocol" : "PCOIP",
|
||||
"AllowDisplayProtocolOverride" : false,
|
||||
"EnableHTMLAccess" : false
|
||||
},
|
||||
"ServerErrorThreshold": null,
|
||||
"MirageConfigurationOverrides": {
|
||||
"OverrideGlobalSetting" : false,
|
||||
"Enabled" : false,
|
||||
"Url" : null
|
||||
}
|
||||
},
|
||||
"AutomatedFarmSpec": {
|
||||
"ProvisioningType": "INSTANT_CLONE_ENGINE",
|
||||
"VirtualCenter": null,
|
||||
"RdsServerNamingSpec": {
|
||||
"NamingMethod": "PATTERN",
|
||||
"PatternNamingSettings": {
|
||||
"NamingPattern": "ICFarmVMPS",
|
||||
"MaxNumberOfRDSServers": 1
|
||||
}
|
||||
},
|
||||
"VirtualCenterProvisioningSettings": {
|
||||
"EnableProvisioning": true,
|
||||
"StopProvisioningOnError": true,
|
||||
"MinReadyVMsOnVComposerMaintenance": 0,
|
||||
"VirtualCenterProvisioningData": {
|
||||
"ParentVm": "vm-rdsh-ic",
|
||||
"Snapshot": "snap_5",
|
||||
"Datacenter": null,
|
||||
"VmFolder": "Instant_Clone_VMs",
|
||||
"HostOrCluster": "vimal-cluster",
|
||||
"ResourcePool": "vimal-cluster"
|
||||
},
|
||||
"VirtualCenterStorageSettings": {
|
||||
"Datastores": [
|
||||
{
|
||||
"Datastore": "Datastore1",
|
||||
"StorageOvercommit": "UNBOUNDED"
|
||||
}
|
||||
],
|
||||
"UseVSan": false,
|
||||
"ViewComposerStorageSettings": {
|
||||
"UseSeparateDatastoresReplicaAndOSDisks": false,
|
||||
"ReplicaDiskDatastore": null,
|
||||
"UseNativeSnapshots": false,
|
||||
"SpaceReclamationSettings": {
|
||||
"ReclaimVmDiskSpace": false,
|
||||
"ReclamationThresholdGB": null,
|
||||
"BlackoutTimes": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"VirtualCenterNetworkingSettings": {
|
||||
"Nics": null
|
||||
}
|
||||
},
|
||||
"VirtualCenterManagedCommonSettings": {
|
||||
"TransparentPageSharingScope": "VM"
|
||||
},
|
||||
"CustomizationSettings": {
|
||||
"CustomizationType": "CLONE_PREP",
|
||||
"DomainAdministrator": null,
|
||||
"AdContainer": "CN=Computers",
|
||||
"ReusePreExistingAccounts": false,
|
||||
"ClonePrepCustomizationSettings": {
|
||||
"InstantCloneEngineDomainAdministrator": null,
|
||||
"PowerOffScriptName": null,
|
||||
"PowerOffScriptParameters": null,
|
||||
"PostSynchronizationScriptName": null,
|
||||
"PostSynchronizationScriptParameters": null
|
||||
}
|
||||
},
|
||||
"RdsServerMaxSessionsData": {
|
||||
"MaxSessionsType": "UNLIMITED",
|
||||
"MaxSessions": null
|
||||
}
|
||||
},
|
||||
"ManualFarmSpec": null,
|
||||
"NetBiosName" : "ad-vimalg"
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
{
|
||||
"Type": "AUTOMATED",
|
||||
"Data": {
|
||||
"Name": "LCFarmJson",
|
||||
"DisplayName": "FarmJsonTest",
|
||||
"AccessGroup": "Root",
|
||||
"Description": "created LC Farm from PS via JSON",
|
||||
"Enabled": null,
|
||||
"Deleting": false,
|
||||
"Settings": {
|
||||
"DisconnectedSessionTimeoutPolicy" : "NEVER",
|
||||
"DisconnectedSessionTimeoutMinutes" : 1,
|
||||
"EmptySessionTimeoutPolicy" : "AFTER",
|
||||
"EmptySessionTimeoutMinutes" : 1,
|
||||
"LogoffAfterTimeout" : false
|
||||
},
|
||||
"Desktop": null,
|
||||
"DisplayProtocolSettings": {
|
||||
"DefaultDisplayProtocol" : "PCOIP",
|
||||
"AllowDisplayProtocolOverride" : false,
|
||||
"EnableHTMLAccess" : false
|
||||
},
|
||||
"ServerErrorThreshold": null,
|
||||
"MirageConfigurationOverrides": {
|
||||
"OverrideGlobalSetting" : false,
|
||||
"Enabled" : false,
|
||||
"Url" : null
|
||||
}
|
||||
},
|
||||
"AutomatedFarmSpec": {
|
||||
"ProvisioningType": "VIEW_COMPOSER",
|
||||
"VirtualCenter": null,
|
||||
"RdsServerNamingSpec": {
|
||||
"NamingMethod": "PATTERN",
|
||||
"PatternNamingSettings": {
|
||||
"NamingPattern": "LCFarmVMPS",
|
||||
"MaxNumberOfRDSServers": 1
|
||||
}
|
||||
},
|
||||
"VirtualCenterProvisioningSettings": {
|
||||
"EnableProvisioning": true,
|
||||
"StopProvisioningOnError": true,
|
||||
"MinReadyVMsOnVComposerMaintenance": 0,
|
||||
"VirtualCenterProvisioningData": {
|
||||
"ParentVm": "RDSServer",
|
||||
"Snapshot": "RDS_SNAP1",
|
||||
"Datacenter": null,
|
||||
"VmFolder": "Praveen",
|
||||
"HostOrCluster": "CS-1",
|
||||
"ResourcePool": "CS-1"
|
||||
},
|
||||
"VirtualCenterStorageSettings": {
|
||||
"Datastores": [
|
||||
{
|
||||
"Datastore": "Datastore1",
|
||||
"StorageOvercommit": "UNBOUNDED"
|
||||
}
|
||||
],
|
||||
"UseVSan": false,
|
||||
"ViewComposerStorageSettings": {
|
||||
"UseSeparateDatastoresReplicaAndOSDisks": false,
|
||||
"ReplicaDiskDatastore": null,
|
||||
"UseNativeSnapshots": false,
|
||||
"SpaceReclamationSettings": {
|
||||
"ReclaimVmDiskSpace": false,
|
||||
"ReclamationThresholdGB": null,
|
||||
"BlackoutTimes": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"VirtualCenterNetworkingSettings": {
|
||||
"Nics": null
|
||||
}
|
||||
},
|
||||
"VirtualCenterManagedCommonSettings": {
|
||||
"TransparentPageSharingScope": "VM"
|
||||
},
|
||||
"CustomizationSettings": {
|
||||
"CustomizationType": "SYS_PREP",
|
||||
"DomainAdministrator": null,
|
||||
"AdContainer": "CN=Computers",
|
||||
"ReusePreExistingAccounts": false,
|
||||
"SysprepCustomizationSettings": {
|
||||
"CustomizationSpec": "PraveenCust"
|
||||
}
|
||||
},
|
||||
"RdsServerMaxSessionsData": {
|
||||
"MaxSessionsType": "UNLIMITED",
|
||||
"MaxSessions": null
|
||||
}
|
||||
},
|
||||
"ManualFarmSpec": null,
|
||||
"NetBiosName" : "adviewdev"
|
||||
}
|
||||
38
Modules/VMware.Hv.Helper/Json/Farm/ManualFarm.json
Normal file
38
Modules/VMware.Hv.Helper/Json/Farm/ManualFarm.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"Type": "MANUAL",
|
||||
"Data": {
|
||||
"Name": "manualFarmTest",
|
||||
"DisplayName": "manualFarmTest",
|
||||
"AccessGroup": "Root",
|
||||
"Description": "Manual PS Test",
|
||||
"Enabled": null,
|
||||
"Deleting": false,
|
||||
"Settings": {
|
||||
"DisconnectedSessionTimeoutPolicy" : "NEVER",
|
||||
"DisconnectedSessionTimeoutMinutes" : 1,
|
||||
"EmptySessionTimeoutPolicy" : "AFTER",
|
||||
"EmptySessionTimeoutMinutes" : 1,
|
||||
"LogoffAfterTimeout" : false
|
||||
},
|
||||
"Desktop": null,
|
||||
"DisplayProtocolSettings": {
|
||||
"DefaultDisplayProtocol" : "PCOIP",
|
||||
"AllowDisplayProtocolOverride" : false,
|
||||
"EnableHTMLAccess" : false
|
||||
},
|
||||
"ServerErrorThreshold": null,
|
||||
"MirageConfigurationOverrides": {
|
||||
"OverrideGlobalSetting" : false,
|
||||
"Enabled" : false,
|
||||
"Url" : null
|
||||
}
|
||||
},
|
||||
"AutomatedFarmSpec": null,
|
||||
"ManualFarmSpec": {
|
||||
"RdsServers": [
|
||||
{
|
||||
"rdsServer": "RDSServer.adviewdev.eng.vmware.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
118
Modules/VMware.Hv.Helper/Json/Pool/FullClone.json
Normal file
118
Modules/VMware.Hv.Helper/Json/Pool/FullClone.json
Normal file
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"Base": {
|
||||
"Name" : "FulClnJSON",
|
||||
"DisplayName": "FullClonePraJSON",
|
||||
"AccessGroup": "Root",
|
||||
"Description": "create full clone via JSON"
|
||||
},
|
||||
"DesktopSettings": {
|
||||
"enabled": true,
|
||||
"deleting": false,
|
||||
"connectionServerRestrictions": null,
|
||||
"logoffSettings": {
|
||||
"powerPolicy": "TAKE_NO_POWER_ACTION",
|
||||
"automaticLogoffPolicy": "NEVER",
|
||||
"automaticLogoffMinutes": 120,
|
||||
"allowUsersToResetMachines": false,
|
||||
"allowMultipleSessionsPerUser": false,
|
||||
"deleteOrRefreshMachineAfterLogoff": "NEVER",
|
||||
"refreshOsDiskAfterLogoff": "NEVER",
|
||||
"refreshPeriodDaysForReplicaOsDisk": 5,
|
||||
"refreshThresholdPercentageForReplicaOsDisk": 10
|
||||
},
|
||||
"displayProtocolSettings": {
|
||||
"supportedDisplayProtocols": ["PCOIP", "BLAST" ],
|
||||
"defaultDisplayProtocol": "BLAST",
|
||||
"allowUsersToChooseProtocol": true,
|
||||
"pcoipDisplaySettings": {
|
||||
"renderer3D": "DISABLED",
|
||||
"enableGRIDvGPUs": false,
|
||||
"vRamSizeMB": 96,
|
||||
"maxNumberOfMonitors": 3,
|
||||
"maxResolutionOfAnyOneMonitor": "WSXGA_PLUS"
|
||||
},
|
||||
"enableHTMLAccess": true
|
||||
},
|
||||
"flashSettings": {
|
||||
"quality": "NO_CONTROL",
|
||||
"throttling": "DISABLED"
|
||||
},
|
||||
"mirageConfigurationOverrides": {
|
||||
"overrideGlobalSetting": false,
|
||||
"enabled": false,
|
||||
"url": false
|
||||
}
|
||||
},
|
||||
"Type": "AUTOMATED",
|
||||
"AutomatedDesktopSpec": {
|
||||
"ProvisioningType": "VIRTUAL_CENTER",
|
||||
"VirtualCenter": null,
|
||||
"UserAssignment": {
|
||||
"UserAssignment": "DEDICATED",
|
||||
"AutomaticAssignment": true
|
||||
},
|
||||
"VmNamingSpec": {
|
||||
"NamingMethod": "PATTERN",
|
||||
"PatternNamingSettings": {
|
||||
"NamingPattern": "FullClnJson1",
|
||||
"MaxNumberOfMachines": 1,
|
||||
"NumberOfSpareMachines": 1,
|
||||
"ProvisioningTime": "UP_FRONT",
|
||||
"MinNumberOfMachines": null
|
||||
},
|
||||
"SpecificNamingSpec": null
|
||||
},
|
||||
"VirtualCenterProvisioningSettings": {
|
||||
"EnableProvisioning": true,
|
||||
"StopProvisioningOnError": true,
|
||||
"MinReadyVMsOnVComposerMaintenance": 0,
|
||||
"VirtualCenterProvisioningData": {
|
||||
"Template": "powerCLI-VM-TEMPLATE",
|
||||
"ParentVm": null,
|
||||
"Snapshot": null,
|
||||
"Datacenter": null,
|
||||
"VmFolder": "Praveen",
|
||||
"HostOrCluster": "CS-1",
|
||||
"ResourcePool": "CS-1"
|
||||
},
|
||||
"VirtualCenterStorageSettings": {
|
||||
"Datastores": [
|
||||
{
|
||||
"Datastore": "datastore1",
|
||||
"StorageOvercommit": "UNBOUNDED"
|
||||
}
|
||||
],
|
||||
"UseVSan": false,
|
||||
"ViewComposerStorageSettings": null,
|
||||
"ViewStorageAcceleratorSettings": {
|
||||
"UseViewStorageAccelerator": false,
|
||||
"ViewComposerDiskTypes": null,
|
||||
"RegenerateViewStorageAcceleratorDays": null,
|
||||
"BlackoutTimes": null
|
||||
}
|
||||
},
|
||||
"VirtualCenterNetworkingSettings": {
|
||||
"Nics": null
|
||||
}
|
||||
},
|
||||
"VirtualCenterManagedCommonSettings": {
|
||||
"TransparentPageSharingScope": "VM"
|
||||
},
|
||||
"CustomizationSettings": {
|
||||
"CustomizationType": "SYS_PREP",
|
||||
"DomainAdministrator": null,
|
||||
"AdContainer": "CN=Computers",
|
||||
"ReusePreExistingAccounts": false,
|
||||
"NoCustomizationSettings": {
|
||||
"DoNotPowerOnVMsAfterCreation": false
|
||||
},
|
||||
"SysprepCustomizationSettings": {"customizationSpec" : "praveencust"},
|
||||
"QuickprepCustomizationSettings": null,
|
||||
"CloneprepCustomizationSettings": null
|
||||
}
|
||||
},
|
||||
"ManualDesktopSpec": null,
|
||||
"RdsDesktopSpec": null,
|
||||
"GlobalEntitlementData": null,
|
||||
"NetBiosName" : "adviewdev"
|
||||
}
|
||||
142
Modules/VMware.Hv.Helper/Json/Pool/InstantClone.json
Normal file
142
Modules/VMware.Hv.Helper/Json/Pool/InstantClone.json
Normal file
@@ -0,0 +1,142 @@
|
||||
{
|
||||
"Base": {
|
||||
"Name" : "InsClnJSON",
|
||||
"DisplayName": "insPoolPr",
|
||||
"AccessGroup": "ROOT",
|
||||
"Description": "create instant pool"
|
||||
},
|
||||
"DesktopSettings": {
|
||||
"enabled": true,
|
||||
"deleting": false,
|
||||
"connectionServerRestrictions": null,
|
||||
"logoffSettings": {
|
||||
"powerPolicy": "ALWAYS_POWERED_ON",
|
||||
"automaticLogoffPolicy": "NEVER",
|
||||
"automaticLogoffMinutes": 120,
|
||||
"allowUsersToResetMachines": false,
|
||||
"allowMultipleSessionsPerUser": false,
|
||||
"deleteOrRefreshMachineAfterLogoff": "DELETE",
|
||||
"refreshOsDiskAfterLogoff": "NEVER",
|
||||
"refreshPeriodDaysForReplicaOsDisk": 5,
|
||||
"refreshThresholdPercentageForReplicaOsDisk": 10
|
||||
},
|
||||
"displayProtocolSettings": {
|
||||
"supportedDisplayProtocols": ["PCOIP", "BLAST" ],
|
||||
"defaultDisplayProtocol": "BLAST",
|
||||
"allowUsersToChooseProtocol": true,
|
||||
"pcoipDisplaySettings": {
|
||||
"renderer3D": "DISABLED",
|
||||
"enableGRIDvGPUs": false,
|
||||
"vRamSizeMB": 96,
|
||||
"maxNumberOfMonitors": 3,
|
||||
"maxResolutionOfAnyOneMonitor": "WSXGA_PLUS"
|
||||
},
|
||||
"enableHTMLAccess": true
|
||||
},
|
||||
"flashSettings": {
|
||||
"quality": "NO_CONTROL",
|
||||
"throttling": "DISABLED"
|
||||
},
|
||||
"mirageConfigurationOverrides": {
|
||||
"overrideGlobalSetting": false,
|
||||
"enabled": false,
|
||||
"url": false
|
||||
}
|
||||
},
|
||||
"Type": "AUTOMATED",
|
||||
"AutomatedDesktopSpec": {
|
||||
"ProvisioningType": "INSTANT_CLONE_ENGINE",
|
||||
"VirtualCenter": null,
|
||||
"UserAssignment": {
|
||||
"UserAssignment": "FLOATING",
|
||||
"AutomaticAssignment": true
|
||||
},
|
||||
"VmNamingSpec": {
|
||||
"NamingMethod": "PATTERN",
|
||||
"PatternNamingSettings": {
|
||||
"NamingPattern": "inspoolJson1",
|
||||
"MaxNumberOfMachines": 1,
|
||||
"NumberOfSpareMachines": 1,
|
||||
"ProvisioningTime": "UP_FRONT",
|
||||
"MinNumberOfMachines": null
|
||||
},
|
||||
"SpecificNamingSpec": null
|
||||
},
|
||||
"VirtualCenterProvisioningSettings": {
|
||||
"EnableProvisioning": true,
|
||||
"StopProvisioningOnError": true,
|
||||
"MinReadyVMsOnVComposerMaintenance": 0,
|
||||
"VirtualCenterProvisioningData": {
|
||||
"Template": null,
|
||||
"ParentVm": "Agent_pra",
|
||||
"Snapshot": "kb-hotfix",
|
||||
"Datacenter": null,
|
||||
"VmFolder": "Praveen",
|
||||
"HostOrCluster": "CS-1",
|
||||
"ResourcePool": "CS-1"
|
||||
},
|
||||
"VirtualCenterStorageSettings": {
|
||||
"Datastores": [
|
||||
{
|
||||
"Datastore": "datastore1",
|
||||
"StorageOvercommit": "UNBOUNDED"
|
||||
}
|
||||
],
|
||||
"UseVSan": false,
|
||||
"ViewComposerStorageSettings": {
|
||||
"UseSeparateDatastoresReplicaAndOSDisks": false,
|
||||
"ReplicaDiskDatastore": null,
|
||||
"UseNativeSnapshots": false,
|
||||
"SpaceReclamationSettings": {
|
||||
"ReclaimVmDiskSpace": false,
|
||||
"ReclamationThresholdGB": null
|
||||
},
|
||||
"PersistentDiskSettings": {
|
||||
"RedirectWindowsProfile": false,
|
||||
"UseSeparateDatastoresPersistentAndOSDisks": null,
|
||||
"PersistentDiskDatastores": null,
|
||||
"DiskSizeMB": null,
|
||||
"DiskDriveLetter": null
|
||||
},
|
||||
"NonPersistentDiskSettings": {
|
||||
"RedirectDisposableFiles": false,
|
||||
"DiskSizeMB": null,
|
||||
"DiskDriveLetter": null
|
||||
}
|
||||
},
|
||||
"ViewStorageAcceleratorSettings": {
|
||||
"UseViewStorageAccelerator": false,
|
||||
"ViewComposerDiskTypes": null,
|
||||
"RegenerateViewStorageAcceleratorDays": null,
|
||||
"BlackoutTimes": null
|
||||
}
|
||||
},
|
||||
"VirtualCenterNetworkingSettings": {
|
||||
"Nics": null
|
||||
}
|
||||
},
|
||||
"VirtualCenterManagedCommonSettings": {
|
||||
"TransparentPageSharingScope": "VM"
|
||||
},
|
||||
"CustomizationSettings": {
|
||||
"CustomizationType": "CLONE_PREP",
|
||||
"DomainAdministrator": null,
|
||||
"AdContainer": "CN=Computers",
|
||||
"ReusePreExistingAccounts": false,
|
||||
"NoCustomizationSettings": null,
|
||||
"SysprepCustomizationSettings": null,
|
||||
"QuickprepCustomizationSettings": null,
|
||||
"CloneprepCustomizationSettings": {
|
||||
"InstantCloneEngineDomainAdministrator": null,
|
||||
"PowerOffScriptName": null,
|
||||
"PowerOffScriptParameters": null,
|
||||
"PostSynchronizationScriptName": null,
|
||||
"PostSynchronizationScriptParameters": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"ManualDesktopSpec": null,
|
||||
"RdsDesktopSpec": null,
|
||||
"GlobalEntitlementData": null,
|
||||
"NetBiosName" : "adviewdev"
|
||||
}
|
||||
154
Modules/VMware.Hv.Helper/Json/Pool/LinkedClone.json
Normal file
154
Modules/VMware.Hv.Helper/Json/Pool/LinkedClone.json
Normal file
@@ -0,0 +1,154 @@
|
||||
{
|
||||
"Base": {
|
||||
"Name" : "LnkClnJSon",
|
||||
"DisplayName": "praveen linkedclone pool",
|
||||
"AccessGroup": "Root",
|
||||
"Description": "created linkedclone pool from ps"
|
||||
},
|
||||
"DesktopSettings": {
|
||||
"enabled": true,
|
||||
"deleting": false,
|
||||
"connectionServerRestrictions": null,
|
||||
"logoffSettings": {
|
||||
"powerPolicy": "TAKE_NO_POWER_ACTION",
|
||||
"automaticLogoffPolicy": "NEVER",
|
||||
"automaticLogoffMinutes": 120,
|
||||
"allowUsersToResetMachines": false,
|
||||
"allowMultipleSessionsPerUser": false,
|
||||
"deleteOrRefreshMachineAfterLogoff": "NEVER",
|
||||
"refreshOsDiskAfterLogoff": "NEVER",
|
||||
"refreshPeriodDaysForReplicaOsDisk": 5,
|
||||
"refreshThresholdPercentageForReplicaOsDisk": 10
|
||||
},
|
||||
"displayProtocolSettings": {
|
||||
"supportedDisplayProtocols": ["RDP","PCOIP", "BLAST" ],
|
||||
"defaultDisplayProtocol": "PCOIP",
|
||||
"allowUsersToChooseProtocol": true,
|
||||
"pcoipDisplaySettings": {
|
||||
"renderer3D": "DISABLED",
|
||||
"enableGRIDvGPUs": false,
|
||||
"vRamSizeMB": 96,
|
||||
"maxNumberOfMonitors": 3,
|
||||
"maxResolutionOfAnyOneMonitor": "WSXGA_PLUS"
|
||||
},
|
||||
"enableHTMLAccess": true
|
||||
},
|
||||
"flashSettings": {
|
||||
"quality": "NO_CONTROL",
|
||||
"throttling": "DISABLED"
|
||||
},
|
||||
"mirageConfigurationOverrides": {
|
||||
"overrideGlobalSetting": false,
|
||||
"enabled": false,
|
||||
"url": null
|
||||
}
|
||||
},
|
||||
"Type": "AUTOMATED",
|
||||
"AutomatedDesktopSpec": {
|
||||
"ProvisioningType": "VIEW_COMPOSER",
|
||||
"VirtualCenter": null,
|
||||
"UserAssignment": {
|
||||
"UserAssignment": "FLOATING",
|
||||
"AutomaticAssignment": true
|
||||
},
|
||||
"VmNamingSpec": {
|
||||
"NamingMethod": "PATTERN",
|
||||
"PatternNamingSettings": {
|
||||
"NamingPattern": "patternPra1",
|
||||
"MaxNumberOfMachines": 1,
|
||||
"NumberOfSpareMachines": 1,
|
||||
"ProvisioningTime": "UP_FRONT",
|
||||
"MinNumberOfMachines": null
|
||||
},
|
||||
"SpecificNamingSpec": null
|
||||
},
|
||||
"VirtualCenterProvisioningSettings": {
|
||||
"EnableProvisioning": true,
|
||||
"StopProvisioningOnError": true,
|
||||
"MinReadyVMsOnVComposerMaintenance": 0,
|
||||
"VirtualCenterProvisioningData": {
|
||||
"Template": null,
|
||||
"ParentVm": "Agent_pra",
|
||||
"Snapshot": "kb-hotfix",
|
||||
"Datacenter": "Dev-Dc",
|
||||
"VmFolder": "Praveen",
|
||||
"HostOrCluster": "CS-1",
|
||||
"ResourcePool": "CS-1"
|
||||
},
|
||||
"VirtualCenterStorageSettings": {
|
||||
"Datastores": [
|
||||
{
|
||||
"Datastore": "datastore1",
|
||||
"StorageOvercommit": "UNBOUNDED"
|
||||
}
|
||||
],
|
||||
"UseVSan": false,
|
||||
"ViewComposerStorageSettings": {
|
||||
"UseSeparateDatastoresReplicaAndOSDisks": false,
|
||||
"ReplicaDiskDatastore": null,
|
||||
"UseNativeSnapshots": false,
|
||||
"SpaceReclamationSettings": {
|
||||
"ReclaimVmDiskSpace": false,
|
||||
"ReclamationThresholdGB": null,
|
||||
"BlackoutTimes" : null
|
||||
},
|
||||
"PersistentDiskSettings": {
|
||||
"RedirectWindowsProfile": false,
|
||||
"UseSeparateDatastoresPersistentAndOSDisks": null,
|
||||
"PersistentDiskDatastores": null,
|
||||
"DiskSizeMB": null,
|
||||
"DiskDriveLetter": null
|
||||
},
|
||||
"NonPersistentDiskSettings": {
|
||||
"RedirectDisposableFiles": false,
|
||||
"DiskSizeMB": null,
|
||||
"DiskDriveLetter": null
|
||||
}
|
||||
},
|
||||
"ViewStorageAcceleratorSettings": {
|
||||
"UseViewStorageAccelerator": false,
|
||||
"ViewComposerDiskTypes": null,
|
||||
"RegenerateViewStorageAcceleratorDays": null,
|
||||
"BlackoutTimes": null
|
||||
}
|
||||
},
|
||||
"VirtualCenterNetworkingSettings": {
|
||||
"Nics": [
|
||||
{
|
||||
"Nic": "nicName",
|
||||
"NetworkLabelAssignmentSpecs": [
|
||||
{
|
||||
"Enabled" : false,
|
||||
"networkLabel" : null,
|
||||
"maxLabelType" : null,
|
||||
"maxLabel" : null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"VirtualCenterManagedCommonSettings": {
|
||||
"TransparentPageSharingScope": "VM"
|
||||
},
|
||||
"CustomizationSettings": {
|
||||
"CustomizationType": "SYS_PREP",
|
||||
"DomainAdministrator": "administrator",
|
||||
"AdContainer": "CN=Computers",
|
||||
"ReusePreExistingAccounts": false,
|
||||
"NoCustomizationSettings": null,
|
||||
"SysprepCustomizationSettings": {"customizationSpec" : "praveencust"},
|
||||
"QuickprepCustomizationSettings": {
|
||||
"PowerOffScriptName": null,
|
||||
"PowerOffScriptParameters": null,
|
||||
"PostSynchronizationScriptName": null,
|
||||
"PostSynchronizationScriptParameters": null
|
||||
},
|
||||
"CloneprepCustomizationSettings": null
|
||||
}
|
||||
},
|
||||
"ManualDesktopSpec": null,
|
||||
"RdsDesktopSpec": null,
|
||||
"GlobalEntitlementData": null,
|
||||
"NetBiosName" : "adviewdev"
|
||||
}
|
||||
73
Modules/VMware.Hv.Helper/Json/Pool/ManualSpec.json
Normal file
73
Modules/VMware.Hv.Helper/Json/Pool/ManualSpec.json
Normal file
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"Base": {
|
||||
"Name" : "MnlJson",
|
||||
"DisplayName": "MNLPUL",
|
||||
"AccessGroup": "ROOT",
|
||||
"Description": "Manual pool creation"
|
||||
},
|
||||
"DesktopSettings": {
|
||||
"enabled": true,
|
||||
"deleting": false,
|
||||
"connectionServerRestrictions": null,
|
||||
"logoffSettings": {
|
||||
"powerPolicy": "TAKE_NO_POWER_ACTION",
|
||||
"automaticLogoffPolicy": "NEVER",
|
||||
"automaticLogoffMinutes": 120,
|
||||
"allowUsersToResetMachines": false,
|
||||
"allowMultipleSessionsPerUser": false,
|
||||
"deleteOrRefreshMachineAfterLogoff": "NEVER",
|
||||
"refreshOsDiskAfterLogoff": "NEVER",
|
||||
"refreshPeriodDaysForReplicaOsDisk": 5,
|
||||
"refreshThresholdPercentageForReplicaOsDisk": 10
|
||||
},
|
||||
"displayProtocolSettings": {
|
||||
"supportedDisplayProtocols": ["PCOIP", "BLAST" ],
|
||||
"defaultDisplayProtocol": "BLAST",
|
||||
"allowUsersToChooseProtocol": true,
|
||||
"pcoipDisplaySettings": {
|
||||
"renderer3D": "DISABLED",
|
||||
"enableGRIDvGPUs": false,
|
||||
"vRamSizeMB": 96,
|
||||
"maxNumberOfMonitors": 3,
|
||||
"maxResolutionOfAnyOneMonitor": "WSXGA_PLUS"
|
||||
},
|
||||
"enableHTMLAccess": true
|
||||
},
|
||||
"flashSettings": {
|
||||
"quality": "NO_CONTROL",
|
||||
"throttling": "DISABLED"
|
||||
},
|
||||
"mirageConfigurationOverrides": {
|
||||
"overrideGlobalSetting": false,
|
||||
"enabled": false,
|
||||
"url": false
|
||||
}
|
||||
},
|
||||
"Type": "MANUAL",
|
||||
"AutomatedDesktopSpec": null,
|
||||
"ManualDesktopSpec": {
|
||||
"UserAssignment": {
|
||||
"UserAssignment": "FLOATING",
|
||||
"AutomaticAssignment": true
|
||||
},
|
||||
"Source": "VIRTUAL_CENTER",
|
||||
"Machines": [
|
||||
{
|
||||
"Machine" : "Praveen_Agent"
|
||||
}
|
||||
],
|
||||
"VirtualCenter": null,
|
||||
"ViewStorageAcceleratorSettings": {
|
||||
"UseViewStorageAccelerator": false,
|
||||
"ViewComposerDiskTypes": null,
|
||||
"RegenerateViewStorageAcceleratorDays": null,
|
||||
"BlackoutTimes": null
|
||||
},
|
||||
"VirtualCenterManagedCommonSettings": {
|
||||
"TransparentPageSharingScope": "VM"
|
||||
}
|
||||
},
|
||||
"RdsDesktopSpec": null,
|
||||
"GlobalEntitlementData": null
|
||||
|
||||
}
|
||||
27
Modules/VMware.Hv.Helper/Json/Pool/RdsSpec.json
Normal file
27
Modules/VMware.Hv.Helper/Json/Pool/RdsSpec.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"Base": {
|
||||
"Name" : "RdsJson",
|
||||
"DisplayName": "TestRDSPS",
|
||||
"AccessGroup": "Root",
|
||||
"Description": "Testing PS"
|
||||
},
|
||||
"DesktopSettings": {
|
||||
"enabled": true,
|
||||
"deleting": false,
|
||||
"connectionServerRestrictions": null,
|
||||
"logoffSettings": null,
|
||||
"displayProtocolSettings": null,
|
||||
"flashSettings": {
|
||||
"quality": "NO_CONTROL",
|
||||
"throttling": "DISABLED"
|
||||
},
|
||||
"mirageConfigurationOverrides": null
|
||||
},
|
||||
"Type": "RDS",
|
||||
"AutomatedDesktopSpec": null,
|
||||
"ManualDesktopSpec": null,
|
||||
"RdsDesktopSpec": {
|
||||
"Farm": "test1"
|
||||
},
|
||||
"GlobalEntitlementData": null
|
||||
}
|
||||
20
Modules/VMware.Hv.Helper/README.md
Normal file
20
Modules/VMware.Hv.Helper/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
Prerequisites/Steps to use this module:
|
||||
|
||||
1. This module only works for Horizon product E.g. Horizon 7.0.2 and later.
|
||||
2. Install the latest version of Powershell, PowerCLI(6.5) or (later version via psgallery).
|
||||
3. Import HorizonView module by running: Import-Module VMware.VimAutomation.HorizonView.
|
||||
4. Import "VMware.Hv.Helper" module by running: Import-Module -Name "location of this module" or Get-Module -ListAvailable 'VMware.Hv.Helper' | Import-Module.
|
||||
5. Get-Command -Module "This module Name" to list all available functions or Get-Command -Module 'VMware.Hv.Helper'.
|
||||
|
||||
# Example script to connect view API service of Connection Server:
|
||||
|
||||
Import-Module VMware.VimAutomation.HorizonView
|
||||
# Connection to view API service
|
||||
$hvServer = Connect-HVServer -server <connection server IP/FQDN>
|
||||
$hvServices = $hvserver.ExtensionData
|
||||
$csList = $hvServices.ConnectionServer.ConnectionServer_List()
|
||||
# Load this module
|
||||
Get-Module -ListAvailable 'VMware.Hv.Helper' | Import-Module
|
||||
Get-Command -Module 'VMware.Hv.Helper'
|
||||
# Use advanced functions of this module
|
||||
New-HVPool -spec 'path to InstantClone.json file'
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"data.description" : "update through edit farm function",
|
||||
"data.displayName" : "LCFarmTestUpdated1",
|
||||
"data.displayProtocolSettings.defaultDisplayProtocol" : "PCOIP",
|
||||
"automatedFarmData.virtualCenterManagedCommonSettings.transparentPageSharingScope" : "FARM"
|
||||
}
|
||||
5
Modules/VMware.Hv.Helper/Set-HVFarm/ManualEditFarm.json
Normal file
5
Modules/VMware.Hv.Helper/Set-HVFarm/ManualEditFarm.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"data.description" : "update through edit farm function",
|
||||
"data.displayName" : "ManualFarmTestUpdated1",
|
||||
"data.displayProtocolSettings.defaultDisplayProtocol" : "PCOIP"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"generalData.clientMaxSessionTimePolicy": "TIMEOUT_AFTER",
|
||||
"generalData.clientMaxSessionTimeMinutes": 600,
|
||||
"generalData.clientIdleSessionTimeoutPolicy": "NEVER",
|
||||
"generalData.clientIdleSessionTimeoutMinutes": null,
|
||||
"generalData.clientSessionTimeoutMinutes": 1200,
|
||||
"generalData.desktopSSOTimeoutPolicy": "DISABLE_AFTER",
|
||||
"generalData.desktopSSOTimeoutMinutes": 15,
|
||||
"generalData.applicationSSOTimeoutPolicy": "ALWAYS_ENABLED",
|
||||
"generalData.applicationSSOTimeoutMinutes": null,
|
||||
"generalData.viewAPISessionTimeoutMinutes": 10,
|
||||
"generalData.preLoginMessage": null,
|
||||
"generalData.displayWarningBeforeForcedLogoff": true,
|
||||
"generalData.forcedLogoffTimeoutMinutes": 5,
|
||||
"generalData.forcedLogoffMessage": "Your desktop is scheduled for an important update and will shut down in 5 minutes. Please save any unsaved work now",
|
||||
"generalData.enableServerInSingleUserMode": false,
|
||||
"generalData.storeCALOnBroker": false,
|
||||
"generalData.storeCALOnClient": false,
|
||||
"securityData.reauthSecureTunnelAfterInterruption": true,
|
||||
"securityData.messageSecurityMode": "ENHANCED",
|
||||
"securityData.enableIPSecForSecurityServerPairing": true
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"base.description" : "update through edit pool function",
|
||||
"base.displayName" : "Henry2DspNm",
|
||||
"desktopSettings.displayProtocolSettings.defaultDisplayProtocol" : "BLAST",
|
||||
"automatedDesktopData.virtualCenterProvisioningSettings.virtualCenterStorageSettings.viewStorageAcceleratorSettings.useViewStorageAccelerator" : true,
|
||||
"automatedDesktopData.virtualCenterProvisioningSettings.virtualCenterStorageSettings.viewStorageAcceleratorSettings.viewComposerDiskTypes" : "OS_DISKS",
|
||||
"automatedDesktopData.virtualCenterProvisioningSettings.virtualCenterStorageSettings.viewStorageAcceleratorSettings.regenerateViewStorageAcceleratorDays" : 8
|
||||
}
|
||||
8
Modules/VMware.Hv.Helper/Set-HVPool/ManualEditPool.json
Normal file
8
Modules/VMware.Hv.Helper/Set-HVPool/ManualEditPool.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"base.description" : "update through edit pool",
|
||||
"base.displayName" : "pooldisp",
|
||||
"desktopSettings.displayProtocolSettings.defaultDisplayProtocol" : "BLAST",
|
||||
"manualDesktopData.viewStorageAcceleratorSettings.useViewStorageAccelerator" : true,
|
||||
"manualDesktopData.viewStorageAcceleratorSettings.viewComposerDiskTypes" : "OS_DISKS",
|
||||
"manualDesktopData.viewStorageAcceleratorSettings.regenerateViewStorageAcceleratorDays" : 8
|
||||
}
|
||||
6
Modules/VMware.Hv.Helper/Set-HVPool/RdsEditPool.json
Normal file
6
Modules/VMware.Hv.Helper/Set-HVPool/RdsEditPool.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"base.description" : "update through edit pool function",
|
||||
"base.displayName" : "RDS2DspNm",
|
||||
"desktopSettings.flashSettings.quality" : "LOW",
|
||||
"desktopSettings.flashSettings.throttling" : "CONSERVATIVE"
|
||||
}
|
||||
262
Modules/VMware.Hv.Helper/VMware.HV.Helper.format.ps1xml
Normal file
262
Modules/VMware.Hv.Helper/VMware.HV.Helper.format.ps1xml
Normal file
@@ -0,0 +1,262 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Configuration>
|
||||
<ViewDefinitions>
|
||||
<View>
|
||||
<Name>VMware.HV.DesktopSummaryView</Name>
|
||||
<ViewSelectedBy>
|
||||
<TypeName>VMware.HV.DesktopSummaryView</TypeName>
|
||||
</ViewSelectedBy>
|
||||
<TableControl>
|
||||
<TableHeaders>
|
||||
<TableColumnHeader>
|
||||
<Width>12</Width>
|
||||
<Label>Name</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>16</Width>
|
||||
<Label>DisplayName</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>12</Width>
|
||||
<Label>Type</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>18</Width>
|
||||
<Label>Source</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>16</Width>
|
||||
<Label>User Assignment</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>8</Width>
|
||||
<Label>Entitled</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>7</Width>
|
||||
<Label>Enabled</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>10</Width>
|
||||
<Label>Sessions</Label>
|
||||
<Alignment>Right</Alignment>
|
||||
</TableColumnHeader>
|
||||
</TableHeaders>
|
||||
<TableRowEntries>
|
||||
<TableRowEntry>
|
||||
<TableColumnItems>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.desktopSummaryData.name</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.desktopSummaryData.displayName</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.desktopSummaryData.type</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.desktopSummaryData.source</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.desktopSummaryData.userAssignment</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>
|
||||
$filterContains = Get-HVQueryFilter localData.desktops -contains ([VMware.Hv.DesktopId[]]$_.id)
|
||||
$GlobalfilterContains = Get-HVQueryFilter localData.desktops -contains ([VMware.Hv.DesktopId[]]$_.id)
|
||||
Try {
|
||||
$results += Get-HVQueryResult -EntityType EntitledUserOrGroupLocalSummaryView -Filter $filterContains
|
||||
$results += Get-HVQueryResult -EntityType EntitledUserOrGroupGlobalSummaryView -Filter $GlobalfilterContains
|
||||
} Catch {
|
||||
#Do nothing
|
||||
}
|
||||
$results.length
|
||||
</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.desktopSummaryData.enabled</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.desktopSummaryData.numSessions</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
</TableColumnItems>
|
||||
</TableRowEntry>
|
||||
</TableRowEntries>
|
||||
</TableControl>
|
||||
</View>
|
||||
<View>
|
||||
<Name>VMware.HV.DesktopSummaryViewList</Name>
|
||||
<ViewSelectedBy>
|
||||
<TypeName>VMware.HV.DesktopSummaryView</TypeName>
|
||||
</ViewSelectedBy>
|
||||
<ListControl>
|
||||
<ListEntries>
|
||||
<ListEntry>
|
||||
<ListItems>
|
||||
<ListItem>
|
||||
<Label>Name</Label>
|
||||
<ScriptBlock>$_.desktopSummaryData.name</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>DisplayName</Label>
|
||||
<ScriptBlock>$_.desktopSummaryData.displayName</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Type</Label>
|
||||
<ScriptBlock>$_.desktopSummaryData.type</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Source</Label>
|
||||
<ScriptBlock>$_.desktopSummaryData.source</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>User Assignment</Label>
|
||||
<ScriptBlock>$_.desktopSummaryData.userAssignment</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Entitled</Label>
|
||||
<ScriptBlock>
|
||||
$filterContains = Get-HVQueryFilter localData.desktops -contains ([VMware.Hv.DesktopId[]]$_.id)
|
||||
$GlobalfilterContains = Get-HVQueryFilter localData.desktops -contains ([VMware.Hv.DesktopId[]]$_.id)
|
||||
Try {
|
||||
$results += Get-HVQueryResult -EntityType EntitledUserOrGroupLocalSummaryView -Filter $filterContains
|
||||
$results += Get-HVQueryResult -EntityType EntitledUserOrGroupGlobalSummaryView -Filter $GlobalfilterContains
|
||||
} Catch {
|
||||
#Do nothing
|
||||
}
|
||||
$results.length
|
||||
</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Enabled</Label>
|
||||
<ScriptBlock>$_.desktopSummaryData.enabled</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Sessions</Label>
|
||||
<ScriptBlock>$_.desktopSummaryData.numSessions</ScriptBlock>
|
||||
</ListItem>
|
||||
</ListItems>
|
||||
</ListEntry>
|
||||
</ListEntries>
|
||||
</ListControl>
|
||||
</View>
|
||||
<View>
|
||||
<Name>VMware.HV.MachineNamesView</Name>
|
||||
<ViewSelectedBy>
|
||||
<TypeName>VMware.HV.MachineNamesView</TypeName>
|
||||
</ViewSelectedBy>
|
||||
<TableControl>
|
||||
<TableHeaders>
|
||||
<TableColumnHeader>
|
||||
<Width>15</Width>
|
||||
<Label>Machine</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>12</Width>
|
||||
<Label>DesktopPool</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>12</Width>
|
||||
<Label>DNS Name</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>8</Width>
|
||||
<Label>User</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>15</Width>
|
||||
<Label>Host</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>5</Width>
|
||||
<Label>Agent</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>10</Width>
|
||||
<Label>Datastore</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>15</Width>
|
||||
<Label>Status</Label>
|
||||
</TableColumnHeader>
|
||||
</TableHeaders>
|
||||
<TableRowEntries>
|
||||
<TableRowEntry>
|
||||
<TableColumnItems>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.Base.Name</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.NamesData.desktopName</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.Base.DnsName</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.NamesData.UserName</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.ManagedMachineNamesData.HostName</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.Base.AgentVersion</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.ManagedMachineNamesData.DatastorePaths</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.Base.BasicState</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
</TableColumnItems>
|
||||
</TableRowEntry>
|
||||
</TableRowEntries>
|
||||
</TableControl>
|
||||
</View>
|
||||
<View>
|
||||
<Name>VMware.HV.MachineNamesViewList</Name>
|
||||
<ViewSelectedBy>
|
||||
<TypeName>VMware.HV.MachineNamesView</TypeName>
|
||||
</ViewSelectedBy>
|
||||
<ListControl>
|
||||
<ListEntries>
|
||||
<ListEntry>
|
||||
<ListItems>
|
||||
<ListItem>
|
||||
<Label>Name</Label>
|
||||
<ScriptBlock>$_.Base.Name</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>DisplayName</Label>
|
||||
<ScriptBlock>$_.NamesData.desktopName</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Type</Label>
|
||||
<ScriptBlock>$_.Base.DnsName</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Source</Label>
|
||||
<ScriptBlock>$_.NamesData.UserName</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>User Assignment</Label>
|
||||
<ScriptBlock>$_.ManagedMachineNamesData.HostName</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Agent</Label>
|
||||
<ScriptBlock>$_.Base.AgentVersion</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Datastore</Label>
|
||||
<ScriptBlock>$_.ManagedMachineNamesData.DatastorePaths</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Status</Label>
|
||||
<ScriptBlock>$_.Base.BasicState</ScriptBlock>
|
||||
</ListItem>
|
||||
</ListItems>
|
||||
</ListEntry>
|
||||
</ListEntries>
|
||||
</ListControl>
|
||||
</View>
|
||||
</ViewDefinitions>
|
||||
</Configuration>
|
||||
95
Modules/VMware.Hv.Helper/VMware.HV.Helper.psd1
Normal file
95
Modules/VMware.Hv.Helper/VMware.HV.Helper.psd1
Normal file
@@ -0,0 +1,95 @@
|
||||
#
|
||||
# Module manifest for module 'VMware.HV'
|
||||
#
|
||||
# Generated by: "VMware"
|
||||
#
|
||||
# Generated on: 9/20/2016
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
# RootModule = ''
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.1'
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '6d3f7fb5-4e52-43d8-91e1-f65f72532a1d'
|
||||
|
||||
# Author of this module
|
||||
Author = 'VMware'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'VMware, Inc.'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = 'Copyright (c) 2016 VMware, Inc. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
# Description = 'This Windows PowerShell script module contains Advanced functions of VIEW API Service.'
|
||||
|
||||
# Minimum version of the Windows PowerShell engine required by this module
|
||||
# PowerShellVersion = ''
|
||||
|
||||
# Name of the Windows PowerShell host required by this module
|
||||
# PowerShellHostName = ''
|
||||
|
||||
# Minimum version of the Windows PowerShell host required by this module
|
||||
# PowerShellHostVersion = ''
|
||||
|
||||
# Minimum version of the .NET Framework required by this module
|
||||
# DotNetFrameworkVersion = ''
|
||||
|
||||
# Minimum version of the common language runtime (CLR) required by this module
|
||||
# CLRVersion = ''
|
||||
|
||||
# Processor architecture (None, X86, Amd64) required by this module
|
||||
# ProcessorArchitecture = ''
|
||||
|
||||
# Modules that must be imported into the global environment prior to importing this module
|
||||
RequiredModules = @('VMware.VimAutomation.HorizonView')
|
||||
|
||||
# Assemblies that must be loaded prior to importing this module
|
||||
# RequiredAssemblies = @()
|
||||
|
||||
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
|
||||
# ScriptsToProcess = @()
|
||||
|
||||
# Type files (.ps1xml) to be loaded when importing this module
|
||||
# TypesToProcess = @()
|
||||
|
||||
# Format files (.ps1xml) to be loaded when importing this module
|
||||
FormatsToProcess = @('VMware.HV.Helper.format.ps1xml')
|
||||
|
||||
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
||||
NestedModules = @('VMware.HV.Helper.psm1')
|
||||
|
||||
# Functions to export from this module
|
||||
FunctionsToExport = '*'
|
||||
|
||||
# Cmdlets to export from this module
|
||||
CmdletsToExport = '*'
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = '*'
|
||||
|
||||
# Aliases to export from this module
|
||||
AliasesToExport = '*'
|
||||
|
||||
# List of all modules packaged with this module.
|
||||
# ModuleList = @()
|
||||
|
||||
# List of all files packaged with this module
|
||||
# FileList = @()
|
||||
|
||||
# Private data to pass to the module specified in RootModule/ModuleToProcess
|
||||
# PrivateData = ''
|
||||
|
||||
# HelpInfo URI of this module
|
||||
# HelpInfoURI = ''
|
||||
|
||||
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
|
||||
# DefaultCommandPrefix = ''
|
||||
|
||||
}
|
||||
9825
Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1
Normal file
9825
Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Modules/VMware.VMC/VMware.VMC.psd1
Executable file
BIN
Modules/VMware.VMC/VMware.VMC.psd1
Executable file
Binary file not shown.
323
Modules/VMware.VMC/VMware.VMC.psm1
Normal file
323
Modules/VMware.VMC/VMware.VMC.psm1
Normal file
@@ -0,0 +1,323 @@
|
||||
Function Get-VMCCommand {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: VMware
|
||||
Date: 11/17/2017
|
||||
Organization: VMware
|
||||
Blog: http://vmware.com/go/powercli
|
||||
Twitter: @powercli
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Returns all cmdlets for VMware Cloud on AWS
|
||||
.DESCRIPTION
|
||||
This cmdlet will allow you to return all cmdlets included in the VMC module
|
||||
.EXAMPLE
|
||||
Get-VMCCommand
|
||||
.EXAMPLE
|
||||
Get-Command -Module VMware.VMC
|
||||
.NOTES
|
||||
You can either use this cmdlet or the Get-Command cmdlet as seen in Example 2
|
||||
#>
|
||||
Get-command -Module VMware.VimAutomation.Vmc
|
||||
Get-Command -Module VMware.VMC
|
||||
|
||||
}
|
||||
Function Connect-VMCVIServer {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: VMware
|
||||
Date: 11/17/2017
|
||||
Organization: VMware
|
||||
Blog: http://vmware.com/go/powercli
|
||||
Twitter: @powercli
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Cmdlet to connect to your VMC vCenter Server
|
||||
.DESCRIPTION
|
||||
This will connect you to both the VMC ViServer as well as the CiSServer at the same time.
|
||||
.EXAMPLE
|
||||
Connect-VMCVIServer -Server <VMC vCenter address> -User <Username> -Password <Password>
|
||||
.NOTES
|
||||
Easiest way is to pipe through your credentials from Get-VMCSDDCDefaultCredential
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$true)]$Org,
|
||||
[Parameter(Mandatory=$true)]$Sddc,
|
||||
[switch]$Autologin
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
|
||||
$creds = Get-VMCSDDCDefaultCredential -Org $Org -Sddc $Sddc
|
||||
Write-Host "Connecting to VMC vCenter Server" $creds.vc_public_ip
|
||||
Connect-VIServer -Server $creds.vc_public_ip -User $creds.cloud_username -Password $creds.cloud_password | Add-Member -MemberType Noteproperty -Name Location -Value "VMC"
|
||||
Write-Host "Connecting to VMC CIS Endpoint" $creds.vc_public_ip
|
||||
Connect-CisServer -Server $creds.vc_public_ip -User $creds.cloud_username -Password $creds.cloud_password | Add-Member -MemberType Noteproperty -Name Location -Value "VMC"
|
||||
}
|
||||
}
|
||||
Function Get-VMCOrg {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: VMware
|
||||
Date: 11/17/2017
|
||||
Organization: VMware
|
||||
Blog: http://vmware.com/go/powercli
|
||||
Twitter: @powercli
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Return the Orgs that you are a part of
|
||||
.DESCRIPTION
|
||||
Depending on what you've purchased, you may be a part of one or more VMC Orgs. This will return your orgs
|
||||
.EXAMPLE
|
||||
Get-VMCOrg
|
||||
.EXAMPLE
|
||||
Get-VMCOrg -Name <Org Name>
|
||||
.NOTES
|
||||
Return all the info about the orgs you are a part of
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$false)]$Name
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use Connect-VMC to connect" } Else {
|
||||
$orgService = Get-VMCService com.vmware.vmc.orgs
|
||||
if ($PSBoundParameters.ContainsKey("Name")){
|
||||
$orgs = $orgService.list() | Where {$_.display_name -match $Name}
|
||||
} Else {
|
||||
$orgs = $orgService.list()
|
||||
}
|
||||
$Orgs | Select display_name, name, user_name, created, id
|
||||
}
|
||||
}
|
||||
Function Get-VMCSDDC {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: VMware
|
||||
Date: 11/17/2017
|
||||
Organization: VMware
|
||||
Blog: http://vmware.com/go/powercli
|
||||
Twitter: @powercli
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Returns all of the SDDCs you are associated to
|
||||
.DESCRIPTION
|
||||
Returns all of the SDDCs ayou are associated to
|
||||
.EXAMPLE
|
||||
Get-VMCSDDC -Org <Org Name>
|
||||
.EXAMPLE
|
||||
Get-VMCSDDC -Name <SDDC Name> -Org <Org Name>
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$True)]$Org,
|
||||
[Parameter(Mandatory=$false)]$Name
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
|
||||
if ($PSBoundParameters.ContainsKey("Org")){
|
||||
$orgs = Get-VMCOrg -Name $Org
|
||||
} else {
|
||||
$orgs = Get-VMCOrg
|
||||
}
|
||||
|
||||
foreach ($org in $orgs) {
|
||||
$orgID = $org.ID
|
||||
$sddcService = Get-VMCService com.vmware.vmc.orgs.sddcs
|
||||
if ($PSBoundParameters.ContainsKey("Name")){
|
||||
$sddcService.list($OrgID) | Where {$_.name -match $Name}
|
||||
} Else {
|
||||
$sddcService.list($OrgID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Function Get-VMCTask {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: VMware
|
||||
Date: 11/17/2017
|
||||
Organization: VMware
|
||||
Blog: http://vmware.com/go/powercli
|
||||
Twitter: @powercli
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Returns all of the VMC Tasks
|
||||
.DESCRIPTION
|
||||
Returns all of the VMC Tasks that have either occurred or are in process
|
||||
.EXAMPLE
|
||||
Get-VMCTask
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$True)]$Org
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
|
||||
if ($PSBoundParameters.ContainsKey("Org")){
|
||||
$orgs = Get-VMCOrg -Name $Org
|
||||
} else {
|
||||
$orgs = Get-VMCOrg
|
||||
}
|
||||
|
||||
foreach ($org in $orgs) {
|
||||
$orgID = $org.ID
|
||||
$taskService = Get-VMCService com.vmware.vmc.orgs.tasks
|
||||
$taskService.list($OrgID) | Select * -ExcludeProperty Help
|
||||
}
|
||||
}
|
||||
}
|
||||
Function Get-VMCSDDCDefaultCredential {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: VMware
|
||||
Date: 11/17/2017
|
||||
Organization: VMware
|
||||
Blog: http://vmware.com/go/powercli
|
||||
Twitter: @powercli
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Returns the default credential for the SDDC
|
||||
.DESCRIPTION
|
||||
Returns the default credential for the sddc
|
||||
.EXAMPLE
|
||||
Get-VMCSDDCDefaultCredential -Org <Org Name>
|
||||
.EXAMPLE
|
||||
Get-VMCSDDCDefaultCredential -Sddc <SDDC Name> -Org <Org Name>
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$true)]$Org,
|
||||
[Parameter(Mandatory=$false)]$Sddc
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
|
||||
if ($PSBoundParameters.ContainsKey("Sddc")){
|
||||
$sddcs = Get-VMCSDDC -Name $Sddc -Org $Org
|
||||
} else {
|
||||
$sddcs = Get-VMCSDDC -Org $Org
|
||||
}
|
||||
|
||||
foreach ($sddc in $sddcs) {
|
||||
$sddc.resource_config | Select-object vc_url, vc_management_ip, vc_public_ip, cloud_username, cloud_password
|
||||
}
|
||||
}
|
||||
}
|
||||
Function Get-VMCSDDCPublicIP {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: VMware
|
||||
Date: 11/17/2017
|
||||
Organization: VMware
|
||||
Blog: http://vmware.com/go/powercli
|
||||
Twitter: @powercli
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Returns your Public IPs
|
||||
.DESCRIPTION
|
||||
Returns your Public IPs
|
||||
.EXAMPLE
|
||||
Get-VMCSDDCPublicIP -Org <Org Name>
|
||||
.EXAMPLE
|
||||
Get-VMCSDDCPublicIP -Sddc <SDDC Name> -Org <Org Name>
|
||||
.NOTES
|
||||
Return your Public IPs that you have assigned to your account
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$true)]$Org,
|
||||
[Parameter(Mandatory=$false)]$Sddc
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
|
||||
if ($PSBoundParameters.ContainsKey("Sddc")){
|
||||
$sddcs = Get-VMCSDDC -Name $Sddc -Org $Org
|
||||
} else {
|
||||
$sddcs = Get-VMCSDDC -Org $Org
|
||||
}
|
||||
|
||||
foreach ($sddc in $sddcs) {
|
||||
$sddc.resource_config.Public_ip_pool
|
||||
}
|
||||
}
|
||||
}
|
||||
Function Get-VMCVMHost {
|
||||
Param (
|
||||
[Parameter(Mandatory=$false)]$Sddc,
|
||||
[Parameter(Mandatory=$true)]$Org
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
|
||||
if ($PSBoundParameters.ContainsKey("Sddc")){
|
||||
$sddcs = Get-VMCSDDC -Name $Sddc -Org $Org
|
||||
} else {
|
||||
$sddcs = Get-VMCSDDC -Org $Org
|
||||
}
|
||||
|
||||
$results = @()
|
||||
foreach ($sddc in $sddcs) {
|
||||
foreach ($vmhost in $sddc.resource_config.esx_hosts) {
|
||||
$tmp = [pscustomobject] @{
|
||||
esx_id = $vmhost.esx_id;
|
||||
name = $vmhost.name;
|
||||
hostname = $vmhost.hostname;
|
||||
esx_state = $vmhost.esx_state;
|
||||
sddc_id = $sddc.id;
|
||||
org_id = $sddc.org_id;
|
||||
}
|
||||
$results += $tmp
|
||||
}
|
||||
$results
|
||||
}
|
||||
}
|
||||
}
|
||||
Function Get-VMCSDDCVersion {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: VMware
|
||||
Date: 11/17/2017
|
||||
Organization: VMware
|
||||
Blog: http://vmware.com/go/powercli
|
||||
Twitter: @powercli
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Returns SDDC Version
|
||||
.DESCRIPTION
|
||||
Returns Version of the SDDC
|
||||
.EXAMPLE
|
||||
Get-VMCSDDCVersion -Name <SDDC Name> -Org <Org Name>
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$True)]$Org,
|
||||
[Parameter(Mandatory=$false)]$Name
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
|
||||
if ($PSBoundParameters.ContainsKey("Org")){
|
||||
$orgs = Get-VMCOrg -Name $Org
|
||||
} else {
|
||||
$orgs = Get-VMCOrg
|
||||
}
|
||||
|
||||
foreach ($org in $orgs) {
|
||||
$orgID = $org.ID
|
||||
$sddcService = Get-VMCService com.vmware.vmc.orgs.sddcs
|
||||
if ($PSBoundParameters.ContainsKey("Name")){
|
||||
($sddcService.list($OrgID) | Where {$_.name -match $Name}).resource_config.sddc_manifest | Select *version
|
||||
} Else {
|
||||
($sddcService.list($OrgID)).resource_config.sddc_manifest | Select *version
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', 'Get-VMCSDDCVersion'
|
||||
7
Modules/VMware.VMEncryption/README.md
Normal file
7
Modules/VMware.VMEncryption/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Prerequisites/Steps to use this module:
|
||||
|
||||
1. This module only works for vSphere products that support VM Encryption. E.g. vSphere 6.5 and later.
|
||||
2. All the functions in this module only work for KMIP Servers.
|
||||
3. Install the latest version of Powershell and PowerCLI(6.5).
|
||||
4. Import this module by running: Import-Module -Name "location of this module"
|
||||
5. Get-Command -Module "This module Name" to list all available functions.
|
||||
BIN
Modules/VMware.VMEncryption/VMware.VMEncryption.psd1
Normal file
BIN
Modules/VMware.VMEncryption/VMware.VMEncryption.psd1
Normal file
Binary file not shown.
2114
Modules/VMware.VMEncryption/VMware.VMEncryption.psm1
Normal file
2114
Modules/VMware.VMEncryption/VMware.VMEncryption.psm1
Normal file
File diff suppressed because it is too large
Load Diff
34
Modules/Vi-Module/README.md
Normal file
34
Modules/Vi-Module/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
##  <b>V</b>Mware <b>i</b>nfrastructure <b>Module</b>
|
||||
|
||||
### <ins>[Vi-Module.psm1</ins>] (https://github.com/vmware/PowerCLI-Example-Scripts/tree/master/Modules/Vi-Module)
|
||||
|
||||
To install this module, drop the entire '<b>Vi-Module</b>' folder into one of your module directories.
|
||||
|
||||
The default PowerShell module paths are listed in the `$env:PSModulePath` environment variable.
|
||||
|
||||
To make it look better, split the paths in this manner `$env:PSModulePath -split ';'`
|
||||
|
||||
The default per-user module path is: `"$env:HOMEDRIVE$env:HOMEPATH\Documents\WindowsPowerShell\Modules"`.
|
||||
|
||||
The default computer-level module path is: `"$env:windir\System32\WindowsPowerShell\v1.0\Modules"`.
|
||||
|
||||
To use the module, type following command: `Import-Module Vi-Module -Force -Verbose`.
|
||||
|
||||
To see the commands imported, type `Get-Command -Module Vi-Module`.
|
||||
|
||||
For help on each individual cmdlet or function, run `Get-Help CmdletName -Full [-Online][-Examples]`.
|
||||
|
||||
#### <b><ins>Vi-Module Cmdlets:</ins></b>
|
||||
|
||||
|No|Cmdlet|Description|
|
||||
|----|----|----|
|
||||
|1|<b>[Get-RDM</b>] (http://www.ps1code.com/single-post/2015/10/16/How-to-get-RDM-Raw-Device-Mappings-disks-using-PowerCLi)|Report all VM with their RDM disks|
|
||||
|2|<b>[Convert-VmdkThin2EZThick</b>] (http://www.ps1code.com/single-post/2015/11/05/How-to-convert-Thin-Provision-VMDK-disks-to-Eager-Zeroed-Thick-using-PowerCLi)|Inflate thin virtual disks|
|
||||
|3|<b>[Find-VcVm</b>] (https://cloud.githubusercontent.com/assets/6964549/17361776/d5dff80e-597a-11e6-85a2-a782db875f78.png)|Search VCenter VM throw direct connection to group of ESXi hosts. Thanks to <i>VMGU.ru</i> for the [article] (http://www.vmgu.ru/news/vmware-vcenter-how-to-find-powered-off)|
|
||||
|4|<b>[Set-PowerCLiTitle</b>] (http://www.ps1code.com/single-post/2015/11/17/ConnectVIServer-deep-dive-or-%C2%ABWhere-am-I-connected-%C2%BB)|Write connected VI servers info to PowerCLi window title bar|
|
||||
|5|<b>[Get-VMHostFirmwareVersion</b>] (http://www.ps1code.com/single-post/2016/1/9/How-to-know-ESXi-servers%E2%80%99-BIOSFirmware-version-using-PowerCLi)|Get a Firmware version and release date of your ESXi hosts|
|
||||
|6|<b>[Compare-VMHostSoftwareVib</b>] (http://www.ps1code.com/single-post/2016/1/10/How-to-compare-installed-VIB-packages-between-two-or-more-ESXi-hosts)|Compare installed VIB packages between two or more ESXi hosts|
|
||||
|7|<b>[Get-VMHostBirthday</b>] (https://cloud.githubusercontent.com/assets/6964549/12399803/c8439dfa-be24-11e5-8141-09199caa301e.png)|Get ESXi hosts' installation date. Thanks to <i>Magnus Andersson</i> for his [idea] (http://vcdx56.com/2016/01/05/find-esxi-installation-date/)|
|
||||
|8|<b>[Enable-VMHostSSH/Disable-VMHostSSH</b>] (http://www.ps1code.com/single-post/2016/02/07/How-to-enabledisable-SSH-on-all-ESXi-hosts-in-a-cluster-using-PowerCLi)|Enable/Disable SSH on all ESXi hosts in a cluster|
|
||||
|9|<b>[Set-VMHostNtpServer</b>] (http://www.ps1code.com/single-post/2016/03/10/How-to-configure-NTP-servers-setting-on-ESXi-hosts-using-PowerCLi)|Set `NTP Servers` setting on ESXi hosts|
|
||||
|10|<b>[Get-Version</b>] (http://www.ps1code.com/single-post/2016/05/25/How-to-know-any-VMware-object%E2%80%99s-version-Use-GetVersion)|Get VMware Virtual Infrastructure objects' version info: `VM`, `ESXi Hosts`, `VDSwitches`, `Datastores`, `VCenters`, `PowerCLi`, `License Keys`|
|
||||
120
Modules/Vi-Module/Vi-Module.psd1
Normal file
120
Modules/Vi-Module/Vi-Module.psd1
Normal file
@@ -0,0 +1,120 @@
|
||||
#
|
||||
# Module manifest for module 'Vi-Module'
|
||||
#
|
||||
# Generated by: Roman Gelman @rgelman75
|
||||
#
|
||||
# Generated on: 8/1/2016
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'Vi-Module'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.0'
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = 'a5ad4817-fbef-41b9-b5e2-714a7a16fb26'
|
||||
|
||||
# Author of this module
|
||||
Author = 'Roman Gelman @rgelman75'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'Taldor Israel'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = '(c) 2016 Roman Gelman @rgelman75. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = 'VMware Virtual Infrastructure Management functions'
|
||||
|
||||
# Minimum version of the Windows PowerShell engine required by this module
|
||||
PowerShellVersion = '3.0'
|
||||
|
||||
# Name of the Windows PowerShell host required by this module
|
||||
# PowerShellHostName = ''
|
||||
|
||||
# Minimum version of the Windows PowerShell host required by this module
|
||||
# PowerShellHostVersion = ''
|
||||
|
||||
# Minimum version of Microsoft .NET Framework required by this module
|
||||
# DotNetFrameworkVersion = ''
|
||||
|
||||
# Minimum version of the common language runtime (CLR) required by this module
|
||||
# CLRVersion = ''
|
||||
|
||||
# Processor architecture (None, X86, Amd64) required by this module
|
||||
# ProcessorArchitecture = ''
|
||||
|
||||
# Modules that must be imported into the global environment prior to importing this module
|
||||
# RequiredModules = @()
|
||||
|
||||
# Assemblies that must be loaded prior to importing this module
|
||||
# RequiredAssemblies = @()
|
||||
|
||||
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
|
||||
# ScriptsToProcess = @()
|
||||
|
||||
# Type files (.ps1xml) to be loaded when importing this module
|
||||
# TypesToProcess = @()
|
||||
|
||||
# Format files (.ps1xml) to be loaded when importing this module
|
||||
# FormatsToProcess = @()
|
||||
|
||||
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
||||
# NestedModules = @()
|
||||
|
||||
# Functions to export from this module
|
||||
FunctionsToExport = '*'
|
||||
|
||||
# Cmdlets to export from this module
|
||||
CmdletsToExport = '*'
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = '*'
|
||||
|
||||
# Aliases to export from this module
|
||||
AliasesToExport = '*'
|
||||
|
||||
# DSC resources to export from this module
|
||||
# DscResourcesToExport = @()
|
||||
|
||||
# List of all modules packaged with this module
|
||||
# ModuleList = @()
|
||||
|
||||
# List of all files packaged with this module
|
||||
# FileList = @()
|
||||
|
||||
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
|
||||
PrivateData = @{
|
||||
|
||||
PSData = @{
|
||||
|
||||
# Tags applied to this module. These help with module discovery in online galleries.
|
||||
# Tags = @()
|
||||
|
||||
# A URL to the license for this module.
|
||||
# LicenseUri = ''
|
||||
|
||||
# A URL to the main website for this project.
|
||||
ProjectUri = 'https://github.com/rgel/PowerCLi'
|
||||
|
||||
# A URL to an icon representing this module.
|
||||
# IconUri = ''
|
||||
|
||||
# ReleaseNotes of this module
|
||||
# ReleaseNotes = ''
|
||||
|
||||
} # End of PSData hashtable
|
||||
|
||||
} # End of PrivateData hashtable
|
||||
|
||||
# HelpInfo URI of this module
|
||||
# HelpInfoURI = ''
|
||||
|
||||
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
|
||||
# DefaultCommandPrefix = ''
|
||||
|
||||
}
|
||||
|
||||
1241
Modules/Vi-Module/Vi-Module.psm1
Normal file
1241
Modules/Vi-Module/Vi-Module.psm1
Normal file
File diff suppressed because it is too large
Load Diff
93
Modules/apply-hardening/apply-hardening.psm1
Normal file
93
Modules/apply-hardening/apply-hardening.psm1
Normal file
@@ -0,0 +1,93 @@
|
||||
function Apply-Hardening {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.11 ver 2.0 Base Release
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: 5.5 U2
|
||||
PowerCLI Version: PowerCLI 6.3 R1, PowerCLI 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Server 2012 R2
|
||||
Keyword: VM, Hardening, Security
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
Applys a set of Hardening options to your VMs
|
||||
|
||||
.Example
|
||||
Get-VM TST* | Apply-Hardening
|
||||
|
||||
.Example
|
||||
$SampleVMs = Get-VM "TST*"
|
||||
Apply-Hardening -VMs $SampleVMs
|
||||
|
||||
.PARAMETER VMs
|
||||
Specify the VMs
|
||||
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipeline=$True,
|
||||
Position=0)]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]
|
||||
$VMs
|
||||
)
|
||||
|
||||
Process {
|
||||
#region: Create Options
|
||||
$ExtraOptions = @{
|
||||
"isolation.tools.diskShrink.disable"="true";
|
||||
"isolation.tools.diskWiper.disable"="true";
|
||||
"isolation.tools.copy.disable"="true";
|
||||
"isolation.tools.paste.disable"="true";
|
||||
"isolation.tools.dnd.disable"="true";
|
||||
"isolation.tools.setGUIOptions.enable"="false";
|
||||
"log.keepOld"="10";
|
||||
"log.rotateSize"="100000"
|
||||
"RemoteDisplay.maxConnections"="2";
|
||||
"RemoteDisplay.vnc.enabled"="false";
|
||||
|
||||
}
|
||||
if ($DebugPreference -eq "Inquire") {
|
||||
Write-Output "VM Hardening Options:"
|
||||
$ExtraOptions | Format-Table -AutoSize
|
||||
}
|
||||
|
||||
$VMConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
|
||||
|
||||
Foreach ($Option in $ExtraOptions.GetEnumerator()) {
|
||||
$OptionValue = New-Object VMware.Vim.optionvalue
|
||||
$OptionValue.Key = $Option.Key
|
||||
$OptionValue.Value = $Option.Value
|
||||
$VMConfigSpec.extraconfig += $OptionValue
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region: Apply Options
|
||||
ForEach ($VM in $VMs){
|
||||
$VMv = Get-VM $VM | Get-View
|
||||
$state = $VMv.Summary.Runtime.PowerState
|
||||
Write-Output "...Starting Reconfiguring VM: $VM "
|
||||
$TaskConf = ($VMv).ReconfigVM_Task($VMConfigSpec)
|
||||
if ($state -eq "poweredOn") {
|
||||
Write-Output "...Migrating VM: $VM "
|
||||
$TaskMig = $VMv.MigrateVM_Task($null, $_.Runtime.Host, 'highPriority', $null)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
17
Modules/rCisTag/Examples/01-Get.ps1
Normal file
17
Modules/rCisTag/Examples/01-Get.ps1
Normal file
@@ -0,0 +1,17 @@
|
||||
# Fetch Cis Server hostname and credentials
|
||||
.\CisConfig.ps1
|
||||
|
||||
|
||||
Connect-rCisServer -Server $cisServer -User $cisUser -Password $cisPswd
|
||||
|
||||
# Get Tag information
|
||||
Get-rCisTag
|
||||
|
||||
# Get Tag Category information
|
||||
Get-rCisTagCategory
|
||||
|
||||
# Get Tag Assignment information
|
||||
Get-rCisTagAssignment
|
||||
|
||||
Disconnect-rCisServer -Server $cisServer -Confirm:$false
|
||||
|
||||
14
Modules/rCisTag/Examples/02-New.ps1
Normal file
14
Modules/rCisTag/Examples/02-New.ps1
Normal file
@@ -0,0 +1,14 @@
|
||||
# Fetch Cis Server hostname and credentials
|
||||
.\CisConfig.ps1
|
||||
|
||||
Connect-rCisServer -Server $cisServer -User $cisUser -Password $cisPswd
|
||||
|
||||
New-rCisTagCategory -Name MyCat1 -Cardinality Single -Description 'Test Tag Category' -EntityType 'VirtualMachine'
|
||||
New-rCisTag -Name MyTag1 -Category MyCat1 -Description 'Test Tag'
|
||||
$vm = Get-VM | Get-Random
|
||||
New-rCisTagAssignment -Entity $vm -Tag MyTag1
|
||||
|
||||
Get-rCisTagAssignment -Tag MyTag1
|
||||
|
||||
Disconnect-rCisServer -Server $cisServer -Confirm:$false
|
||||
|
||||
11
Modules/rCisTag/Examples/03-Set.ps1
Normal file
11
Modules/rCisTag/Examples/03-Set.ps1
Normal file
@@ -0,0 +1,11 @@
|
||||
# Fetch Cis Server hostname and credentials
|
||||
.\CisConfig.ps1
|
||||
|
||||
Connect-rCisServer -Server $cisServer -User $cisUser -Password $cisPswd
|
||||
|
||||
Get-rCisTag -Name MyTag1 | Set-rCisTag -Name MyNewTag1 -Description 'Name changed'
|
||||
|
||||
Get-rCisTagCategory -Name MyCat1 | Set-rCisTagCategory -Cardinality Multiple -Name MyNewCat1 -Description 'Name changed'
|
||||
|
||||
Disconnect-rCisServer -Server $cisServer -Confirm:$false
|
||||
|
||||
13
Modules/rCisTag/Examples/04-Remove.ps1
Normal file
13
Modules/rCisTag/Examples/04-Remove.ps1
Normal file
@@ -0,0 +1,13 @@
|
||||
# Fetch Cis Server hostname and credentials
|
||||
.\CisConfig.ps1
|
||||
|
||||
Connect-rCisServer -Server $cisServer -User $cisUser -Password $cisPswd
|
||||
|
||||
Get-rCisTagAssignment -Tag MyNewTag1 | Remove-rCisTagAssignment -Confirm:$false
|
||||
|
||||
Get-rCisTag -Name MyNewTag1 | Remove-rCisTag -Confirm:$false
|
||||
|
||||
Get-rCisTagCategory -Name MyNewCat1 | Remove-rCisTagCategory -Confirm:$false
|
||||
|
||||
Disconnect-rCisServer -Server $cisServer -Confirm:$false
|
||||
|
||||
20
Modules/rCisTag/Examples/05-Tag-Datastore.ps1
Normal file
20
Modules/rCisTag/Examples/05-Tag-Datastore.ps1
Normal file
@@ -0,0 +1,20 @@
|
||||
# Fetch Cis Server hostname and credentials
|
||||
.\CisConfig.ps1
|
||||
|
||||
Connect-rCisServer -Server $cisServer -User $cisUser -Password $cisPswd
|
||||
|
||||
$catName = 'Homelab'
|
||||
|
||||
# Clean up
|
||||
Get-rCisTagCategory -Name $catName | Remove-rCisTagCategory -Confirm:$false
|
||||
|
||||
# Tag all datastores with their type
|
||||
New-rCisTagCategory -Name HomeLab -Description 'Homelab datastores' -Cardinality Single -EntityType 'Datastore' |
|
||||
New-rCisTag -Name 'VMFS','NFS' -Description 'Datastore type'
|
||||
|
||||
Get-Cluster -Name Cluster1 | Get-Datastore | %{
|
||||
New-rCisTagAssignment -Entity $_ -Tag "$($_.Type)"
|
||||
}
|
||||
|
||||
Disconnect-rCisServer -Server $cisServer -Confirm:$false
|
||||
|
||||
3
Modules/rCisTag/Examples/CisConfig.ps1
Normal file
3
Modules/rCisTag/Examples/CisConfig.ps1
Normal file
@@ -0,0 +1,3 @@
|
||||
$cisServer = 'vcsa.my.domain'
|
||||
$cisUser = 'administrator@vsphere.local'
|
||||
$cisPswd = 'VMware1!'
|
||||
21
Modules/rCisTag/MITLicense.txt
Normal file
21
Modules/rCisTag/MITLicense.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) since 2015 Luc Dekens, Matt Boren
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
15
Modules/rCisTag/README.md
Normal file
15
Modules/rCisTag/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# rCisTag
|
||||
|
||||
A module with cmdlets to provide CRUD functions to
|
||||
* Tags
|
||||
* Tag Categories
|
||||
* Tag Assignments
|
||||
|
||||
The cmdlets use the Cis REST API
|
||||
|
||||
## History
|
||||
|
||||
* Author : **Luc Dekens**
|
||||
* Release :
|
||||
* **0.9.0** First draft
|
||||
|
||||
26
Modules/rCisTag/en-US/about_rCISTag.Help.txt
Normal file
26
Modules/rCisTag/en-US/about_rCISTag.Help.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
TOPIC
|
||||
about_rCISTag
|
||||
|
||||
SHORT DESCRIPTION
|
||||
The rCisTag module provides CRUD functions to work with vSphere Tags
|
||||
|
||||
LONG DESCRIPTION
|
||||
The CisTag module provides CRUD functions to work with vSphere Tags.
|
||||
The functions in the module are based on the REST API
|
||||
|
||||
NOTE
|
||||
The module requires PowerShell 5.0
|
||||
|
||||
TROUBLESHOOTING NOTE
|
||||
|
||||
|
||||
|
||||
EXAMPLES
|
||||
Get-rCisTag
|
||||
|
||||
KEYWORDS
|
||||
|
||||
|
||||
|
||||
SEE ALSO
|
||||
Place related topics here.
|
||||
1793
Modules/rCisTag/en-US/rCISTag-help.xml
Normal file
1793
Modules/rCisTag/en-US/rCISTag-help.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Modules/rCisTag/rCISTag.psd1
Normal file
BIN
Modules/rCisTag/rCISTag.psd1
Normal file
Binary file not shown.
821
Modules/rCisTag/rCISTag.psm1
Normal file
821
Modules/rCisTag/rCISTag.psm1
Normal file
@@ -0,0 +1,821 @@
|
||||
function Disable-SSLValidation{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Disables SSL certificate validation
|
||||
.DESCRIPTION
|
||||
Disable-SSLValidation disables SSL certificate validation by using reflection to implement the System.Net.ICertificatePolicy class.
|
||||
|
||||
Author: Matthew Graeber (@mattifestation)
|
||||
License: BSD 3-Clause
|
||||
.NOTES
|
||||
Reflection is ideal in situations when a script executes in an environment in which you cannot call csc.ese to compile source code. If compiling code is an option, then implementing System.Net.ICertificatePolicy in C# and Add-Type is trivial.
|
||||
.LINK
|
||||
http://www.exploit-monday.com
|
||||
#>
|
||||
|
||||
Set-StrictMode -Version 2
|
||||
|
||||
# You have already run this function
|
||||
if ([System.Net.ServicePointManager]::CertificatePolicy.ToString() -eq 'IgnoreCerts') { Return }
|
||||
|
||||
$Domain = [AppDomain]::CurrentDomain
|
||||
$DynAssembly = New-Object System.Reflection.AssemblyName('IgnoreCerts')
|
||||
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
|
||||
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('IgnoreCerts', $false)
|
||||
$TypeBuilder = $ModuleBuilder.DefineType('IgnoreCerts', 'AutoLayout, AnsiClass, Class, Public, BeforeFieldInit', [System.Object], [System.Net.ICertificatePolicy])
|
||||
$TypeBuilder.DefineDefaultConstructor('PrivateScope, Public, HideBySig, SpecialName, RTSpecialName') | Out-Null
|
||||
$MethodInfo = [System.Net.ICertificatePolicy].GetMethod('CheckValidationResult')
|
||||
$MethodBuilder = $TypeBuilder.DefineMethod($MethodInfo.Name, 'PrivateScope, Public, Virtual, HideBySig, VtableLayoutMask', $MethodInfo.CallingConvention, $MethodInfo.ReturnType, ([Type[]] ($MethodInfo.GetParameters() | % {$_.ParameterType})))
|
||||
$ILGen = $MethodBuilder.GetILGenerator()
|
||||
$ILGen.Emit([Reflection.Emit.Opcodes]::Ldc_I4_1)
|
||||
$ILGen.Emit([Reflection.Emit.Opcodes]::Ret)
|
||||
$TypeBuilder.CreateType() | Out-Null
|
||||
|
||||
# Disable SSL certificate validation
|
||||
[System.Net.ServicePointManager]::CertificatePolicy = New-Object IgnoreCerts
|
||||
}
|
||||
|
||||
function Invoke-vCisRest{
|
||||
param (
|
||||
[String]$Method,
|
||||
[String]$Request,
|
||||
[PSObject]$Body
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
Write-Verbose -Message "$($MyInvocation.MyCommand.Name)"
|
||||
Write-Verbose -Message "`t$($PSCmdlet.ParameterSetName)"
|
||||
Write-Verbose -Message "`tCalled from $($stack = Get-PSCallStack; $stack[1].Command) at $($stack[1].Location)"
|
||||
|
||||
Disable-SSLValidation
|
||||
|
||||
$sRest = @{
|
||||
Uri = "https:/",$Script:CisServer.Server,'rest',$Request -join '/'
|
||||
Method = $Method
|
||||
# Body = &{if($Body){$Body}}
|
||||
Body = &{if($Body){$Body | ConvertTo-Json -Depth 32}}
|
||||
ContentType = 'application/json'
|
||||
Headers = &{
|
||||
if($Script:CisServer.ContainsKey('vmware-api-session-id')){
|
||||
@{
|
||||
'vmware-api-session-id' = "$($Script:CisServer.'vmware-api-session-id')"
|
||||
}
|
||||
}
|
||||
else{
|
||||
@{
|
||||
Authorization = "$($Script:CisServer.AuthHeader)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Try
|
||||
{
|
||||
# $result = Invoke-WebRequest @sRest
|
||||
$result = Invoke-RestMethod @sRest
|
||||
}
|
||||
Catch
|
||||
{
|
||||
|
||||
}
|
||||
$result
|
||||
}
|
||||
}
|
||||
|
||||
function Connect-rCisServer{
|
||||
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Low')]
|
||||
param (
|
||||
[Parameter(Mandatory, Position = 1)]
|
||||
[String]$Server,
|
||||
[Parameter(Mandatory = $True,ValueFromPipeline = $True, Position = 2, ParameterSetName = 'Credential')]
|
||||
[System.Management.Automation.PSCredential]$Credential,
|
||||
[Parameter(Mandatory = $True, Position = 2, ParameterSetName = 'PlainText')]
|
||||
[String]$User,
|
||||
[Parameter(Mandatory = $True, Position = 3, ParameterSetName = 'PlainText')]
|
||||
[String]$Password,
|
||||
[string]$Proxy,
|
||||
[Parameter(DontShow)]
|
||||
[switch]$Fiddler = $false
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
if ($Proxy)
|
||||
{
|
||||
if ($PSDefaultParameterValues.ContainsKey('*:Proxy'))
|
||||
{
|
||||
$PSDefaultParameterValues['*:Proxy'] = $Proxy
|
||||
}
|
||||
else
|
||||
{
|
||||
$PSDefaultParameterValues.Add('*:Proxy', $Proxy)
|
||||
}
|
||||
if ($PSDefaultParameterValues.ContainsKey('*:ProxyUseDefaultCredentials'))
|
||||
{
|
||||
$PSDefaultParameterValues['*:ProxyUseDefaultCredentials'] = $True
|
||||
}
|
||||
else
|
||||
{
|
||||
$PSDefaultParameterValues.Add('*:ProxyUseDefaultCredentials', $True)
|
||||
}
|
||||
}
|
||||
if ($PSCmdlet.ParameterSetName -eq 'PlainText')
|
||||
{
|
||||
$sPswd = ConvertTo-SecureString -String $Password -AsPlainText -Force
|
||||
$CisCredential = New-Object System.Management.Automation.PSCredential -ArgumentList ($User, $sPswd)
|
||||
}
|
||||
if ($PSCmdlet.ParameterSetName -eq 'Credential')
|
||||
{
|
||||
$CisCredential = $Credential
|
||||
}
|
||||
if ($Fiddler)
|
||||
{
|
||||
if (Get-Process -Name fiddler -ErrorAction SilentlyContinue)
|
||||
{
|
||||
if ($PSDefaultParameterValues.ContainsKey('Invoke-RestMethod:Proxy'))
|
||||
{
|
||||
$PSDefaultParameterValues['Invoke-RestMethod:Proxy'] = 'http://127.0.0.1:8888'
|
||||
}
|
||||
else
|
||||
{
|
||||
$PSDefaultParameterValues.Add('Invoke-RestMethod:Proxy', 'http://127.0.0.1:8888')
|
||||
}
|
||||
}
|
||||
}
|
||||
$Script:CisServer = @{
|
||||
Server = $Server
|
||||
AuthHeader = &{
|
||||
$User = $CisCredential.UserName
|
||||
$Password = $CisCredential.GetNetworkCredential().password
|
||||
|
||||
$Encoded = [System.Text.Encoding]::UTF8.GetBytes(($User, $Password -Join ':'))
|
||||
$EncodedPassword = [System.Convert]::ToBase64String($Encoded)
|
||||
"Basic $($EncodedPassword)"
|
||||
}
|
||||
}
|
||||
$sRest = @{
|
||||
Method = 'Post'
|
||||
Request = 'com/vmware/cis/session'
|
||||
}
|
||||
If($PSCmdlet.ShouldProcess("CisServer $($Server)"))
|
||||
{
|
||||
$result = Invoke-vCisRest @sRest
|
||||
|
||||
$Script:CisServer.Add('vmware-api-session-id',$result.value)
|
||||
$Script:CisServer.Remove('AuthHeader')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Disconnect-rCisServer{
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
|
||||
param (
|
||||
[Parameter(Mandatory = $True, Position = 1)]
|
||||
[String]$Server
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
if($Server -ne $Script:CisServer.Server){
|
||||
Write-Warning "You are not connected to server $($Server)"
|
||||
}
|
||||
|
||||
$sRest = @{
|
||||
Method = 'Delete'
|
||||
Request = 'com/vmware/cis/session'
|
||||
}
|
||||
If($PSCmdlet.ShouldProcess("CisServer $($Server)"))
|
||||
{
|
||||
$result = Invoke-vCisRest @sRest
|
||||
$Script:CisServer.Remove('vmware-api-session-id')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-rCisTag{`
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low', DefaultParameterSetName='Name')]
|
||||
param (
|
||||
[Parameter(Position = 1, ParameterSetName='Name')]
|
||||
[String[]]$Name,
|
||||
[Parameter(Position = 2, ParameterSetName='Name',ValueFromPipeline = $true)]
|
||||
[PSObject[]]$Category,
|
||||
[Parameter(Mandatory = $True, Position = 1, ParameterSetName='Id')]
|
||||
[String[]]$Id
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
if($PSCmdlet.ParameterSetName -eq 'Name'){
|
||||
if($Category){
|
||||
$tagIds = $Category | %{
|
||||
$categoryIds = &{if($_ -is [string]){
|
||||
(Get-rCisTagCategory -Name $_).Id
|
||||
}
|
||||
else{
|
||||
$_.Id
|
||||
}}
|
||||
$categoryIds | %{
|
||||
# Get all tags in categories
|
||||
$sRest = @{
|
||||
Method = 'Post'
|
||||
Request = "com/vmware/cis/tagging/tag/id:$([uri]::EscapeDataString($_))?~action=list-tags-for-category"
|
||||
}
|
||||
(Invoke-vCisRest @sRest).value
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
$sRest = @{
|
||||
Method = 'Get'
|
||||
Request = 'com/vmware/cis/tagging/tag'
|
||||
}
|
||||
$tagIds = (Invoke-vCisRest @sRest).value
|
||||
}
|
||||
}
|
||||
else{
|
||||
$tagIds = $Id
|
||||
}
|
||||
|
||||
# Get category details
|
||||
$out = @()
|
||||
$tagIds | where{($PSCmdlet.ParameterSetName -eq 'Id' -and $Id -contains $_) -or $PSCmdlet.ParameterSetName -eq 'Name'} | %{
|
||||
$sRest = @{
|
||||
Method = 'Get'
|
||||
Request = "com/vmware/cis/tagging/tag/id:$([uri]::EscapeDataString($_))"
|
||||
}
|
||||
$result = Invoke-vCisRest @sRest
|
||||
|
||||
if($PSCmdlet.ParameterSetName -eq 'Id' -or ($PSCmdlet.ParameterSetName -eq 'Name' -and ($Name -eq $null -or $Name -contains $result.value.name))){
|
||||
$out += New-Object PSObject -Property @{
|
||||
Description = $result.value.description
|
||||
Id = $result.value.id
|
||||
Name = $result.value.name
|
||||
Category = (Get-rCisTagCategory -Id $result.value.category_id).Name
|
||||
Uid = "$($global:defaultviserver.Id)Tag=$($result.value.id)/"
|
||||
Client = $global:defaultviserver.Client
|
||||
}
|
||||
}
|
||||
}
|
||||
$out | Select-Object Category,Description,Id,Name,Uid,Client
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function Get-rCisTagCategory{
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low', DefaultParameterSetName='Name')]
|
||||
param (
|
||||
[Parameter(Position = 1, ParameterSetName='Name')]
|
||||
[String[]]$Name,
|
||||
[Parameter(Mandatory = $True, Position = 1, ParameterSetName='Id')]
|
||||
[String[]]$Id
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
$txtInfo = (Get-Culture).TextInfo
|
||||
$entityTab = @{
|
||||
'ClusterComputeResource' = 'Cluster'
|
||||
'DistributedVirtualSwitch' = 'DistributedSwitch'
|
||||
'VmwareDistributedVirtualSwitch' = 'DistributedSwitch'
|
||||
'HostSystem' = 'VMHost'
|
||||
'DistributedVirtualPortGroup' = 'DistributedPortGroup'
|
||||
'VirtualApp' = 'VApp'
|
||||
'StoragePod' = 'DatastoreCluster'
|
||||
'Network' = 'VirtualPortGroup'
|
||||
}
|
||||
}
|
||||
|
||||
Process
|
||||
{
|
||||
if($PSCmdlet.ParameterSetName -eq 'Name'){
|
||||
# Get all categories
|
||||
$sRest = @{
|
||||
Method = 'Get'
|
||||
Request = 'com/vmware/cis/tagging/category'
|
||||
}
|
||||
$tagCategoryIds = (Invoke-vCisRest @sRest).value
|
||||
}
|
||||
else{
|
||||
$tagCategoryIds = $Id
|
||||
}
|
||||
|
||||
# Get category details
|
||||
$out = @()
|
||||
$tagCategoryids | where{($PSCmdlet.ParameterSetName -eq 'Id' -and $Id -contains $_) -or $PSCmdlet.ParameterSetName -eq 'Name'} | %{
|
||||
$sRest = @{
|
||||
Method = 'Get'
|
||||
Request = "com/vmware/cis/tagging/category/id:$([uri]::EscapeDataString($_))"
|
||||
}
|
||||
$result = Invoke-vCisRest @sRest
|
||||
if($PSCmdlet.ParameterSetName -eq 'Id' -or ($PSCmdlet.ParameterSetName -eq 'Name' -and ($Name -eq $null -or $Name -contains $result.value.name))){
|
||||
$out += New-Object PSObject -Property @{
|
||||
Description = $result.value.description
|
||||
Cardinality = $txtInfo.ToTitleCase($result.value.cardinality.ToLower())
|
||||
EntityType = @(&{
|
||||
if($result.value.associable_types.Count -eq 0){'All'}
|
||||
else{
|
||||
$result.value.associable_types | %{
|
||||
if($entityTab.ContainsKey($_)){
|
||||
$entityTab.Item($_)
|
||||
}
|
||||
else{$_}
|
||||
}
|
||||
}} | Sort-Object -Unique)
|
||||
Id = $result.value.id
|
||||
Name = $result.value.name
|
||||
Uid = "$($global:defaultviserver.Id)TagCategory=$($result.value.id)/"
|
||||
Client = $global:defaultviserver.Client
|
||||
}
|
||||
}
|
||||
}
|
||||
$out | Select-Object Description,Cardinality,EntityType,Id,Name,Uid,Client
|
||||
}
|
||||
}
|
||||
|
||||
function Get-rCisTagAssignment{
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low')]
|
||||
param (
|
||||
[parameter(Position = 1, ValueFromPipeline = $true)]
|
||||
[PSObject[]]$Entity,
|
||||
[parameter(Position = 2)]
|
||||
[PSObject[]]$Tag,
|
||||
[parameter(Position = 3)]
|
||||
[PSObject[]]$Category
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
if($Category.Count -ne 0 -or $Tag.Count -ne 0){
|
||||
$tagIds = @((Get-rCisTag -Name $Tag -Category $Category).Id)
|
||||
}
|
||||
else{
|
||||
$tagIds = @((Get-rCisTag).Id)
|
||||
}
|
||||
$out = @()
|
||||
}
|
||||
|
||||
Process
|
||||
{
|
||||
foreach($ent in $Entity){
|
||||
if($ent -is [string]){
|
||||
$ent = Get-Inventory -Name $ent -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
$entMoRef = New-Object PSObject -Property @{
|
||||
type = $ent.ExtensionData.MoRef.Type
|
||||
id = $ent.ExtensionData.MoRef.Value
|
||||
}
|
||||
$sRest = @{
|
||||
Method = 'Post'
|
||||
Request = 'com/vmware/cis/tagging/tag-association?~action=list-attached-tags-on-objects'
|
||||
Body = @{
|
||||
object_ids = @($entMoRef)
|
||||
}
|
||||
}
|
||||
$tagObj = (Invoke-vCisRest @sRest).value
|
||||
foreach($obj in @($tagObj)){
|
||||
foreach($tag in ($obj.tag_ids | where{$tagIds -contains $_})){
|
||||
$sMoRef = "$($obj.object_id.type)-$($obj.object_id.id)"
|
||||
$out += New-Object PSObject -Property @{
|
||||
Entity = (Get-View -id $sMoRef -Property Name).Name
|
||||
Tag = (Get-rCisTag -Id $tag).Name
|
||||
Id = 'com.vmware.cis.tagging.TagAssociationModel'
|
||||
Name = 'com.vmware.cis.tagging.TagAssociationModel'
|
||||
Uid = "$($global:defaultviserver.Id)VirtualMachine=$($sMoRef)/TagAssignment=/Tag=$($tag.tag_id)/"
|
||||
Client = $global:defaultviserver.Client
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
End
|
||||
{
|
||||
if($out.Count -eq 0)
|
||||
{
|
||||
$sRest = @{
|
||||
Method = 'Post'
|
||||
Request = 'com/vmware/cis/tagging/tag-association?~action=list-attached-objects-on-tags'
|
||||
Body = @{
|
||||
tag_ids = $tagIds
|
||||
}
|
||||
}
|
||||
$tagObj = (Invoke-vCisRest @sRest).value
|
||||
$out = foreach($tag in @(($tagObj | where{$tagIds -contains $_.tag_id}))){
|
||||
foreach($obj in $tag.object_ids){
|
||||
$sMoRef = "$($obj.type)-$($obj.id)"
|
||||
New-Object PSObject -Property @{
|
||||
Entity = (Get-View -id $sMoRef -Property Name).Name
|
||||
Tag = (Get-rCisTag -Id $tag.tag_id).Name
|
||||
Id = 'com.vmware.cis.tagging.TagAssociationModel'
|
||||
Name = 'com.vmware.cis.tagging.TagAssociationModel'
|
||||
Uid = "$($global:defaultviserver.Id)VirtualMachine=$($sMoRef)/TagAssignment=/Tag=$($tag.tag_id)/"
|
||||
Client = $global:defaultviserver.Client
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$out | Select-Object Uid,Tag,Entity,Id,Name,Client
|
||||
}
|
||||
}
|
||||
|
||||
function New-rCisTag{
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
|
||||
param (
|
||||
[Parameter(Mandatory=$true, Position = 1)]
|
||||
[String[]]$Name,
|
||||
[Parameter(Mandatory=$true, Position = 2,ValueFromPipeline = $true)]
|
||||
[PSObject]$Category,
|
||||
[Parameter(Position = 3)]
|
||||
[string]$Description
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
$out = @()
|
||||
if($Category -is [String]){
|
||||
$Category = Get-rCisTagCategory -Name $Category
|
||||
}
|
||||
$Name | %{
|
||||
$sRest = @{
|
||||
Method = 'Post'
|
||||
Request = 'com/vmware/cis/tagging/tag'
|
||||
Body = @{
|
||||
create_spec = @{
|
||||
category_id = $Category.Id
|
||||
name = $_
|
||||
description = $Description
|
||||
}
|
||||
}
|
||||
}
|
||||
$tagId = (Invoke-vCisRest @sRest).value
|
||||
$out += New-Object PSObject -Property @{
|
||||
Category = $Category.Name
|
||||
Description = $Description
|
||||
Id = $tagId
|
||||
Name = $_
|
||||
Uid = "$($global:defaultviserver.Id)Tag=$($tagId)/"
|
||||
Client = $global:defaultviserver.Client
|
||||
}
|
||||
}
|
||||
$out | Select-Object Category,Description,Id,Name,Uid,Client
|
||||
}
|
||||
}
|
||||
|
||||
function New-rCisTagCategory{
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
|
||||
param (
|
||||
[Parameter(Mandatory=$true, Position = 1)]
|
||||
[String[]]$Name,
|
||||
[Parameter(Position = 2)]
|
||||
[ValidateSet('Single','Multiple')]
|
||||
[string]$Cardinality = 'Single',
|
||||
[Parameter(Position = 3)]
|
||||
[string]$Description,
|
||||
[Parameter(Position = 4)]
|
||||
[string[]]$EntityType
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
$out = @()
|
||||
$Name | %{
|
||||
$sRest = @{
|
||||
Method = 'Post'
|
||||
Request = 'com/vmware/cis/tagging/category'
|
||||
Body = @{
|
||||
create_spec = @{
|
||||
cardinality = $Cardinality.ToUpper()
|
||||
associable_types = @($EntityType)
|
||||
name = $_
|
||||
description = $Description
|
||||
}
|
||||
}
|
||||
}
|
||||
$categoryId = (Invoke-vCisRest @sRest).value
|
||||
$out += New-Object PSObject -Property @{
|
||||
Description = $Description
|
||||
Cardinality = $Cardinality
|
||||
EntityType = @($EntityType)
|
||||
Id = $categoryId
|
||||
Name = $_
|
||||
Uid = "$($global:defaultviserver.Id)TagCategory=$($categoryId)/"
|
||||
Client = $global:defaultviserver.Client
|
||||
}
|
||||
}
|
||||
$out | Select-Object Description,Cardinality,EntityType,Id,Name,Uid,Client
|
||||
}
|
||||
}
|
||||
|
||||
function New-rCisTagAssignment{
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
|
||||
param (
|
||||
[Parameter(Mandatory=$true, Position = 1)]
|
||||
[String[]]$Tag,
|
||||
[Parameter(Mandatory=$true,ValueFromPipeline = $true, Position = 2)]
|
||||
[PSObject[]]$Entity
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
$tagIds = @((Get-rCisTag -Name $Tag).Id)
|
||||
$Entity = foreach($ent in $Entity){
|
||||
if($ent -is [string]){
|
||||
$ent = Get-Inventory -Name $ent -ErrorAction SilentlyContinue
|
||||
}
|
||||
$entMoRef = New-Object PSObject -Property @{
|
||||
type = $ent.ExtensionData.MoRef.Type
|
||||
id = $ent.ExtensionData.MoRef.Value
|
||||
}
|
||||
foreach($tagId in $tagIds){
|
||||
$sRest = @{
|
||||
Method = 'Post'
|
||||
Request = "com/vmware/cis/tagging/tag-association/id:$($tagId)?~action=attach"
|
||||
Body = @{
|
||||
object_id = $entMoRef
|
||||
}
|
||||
}
|
||||
Invoke-vCisRest @sRest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# foreach($ent in
|
||||
# if($Tag.Count -eq 1)
|
||||
# {
|
||||
# $tagId = (Get-rCisTag -Name $Tag).Id
|
||||
# }
|
||||
# elseif($Tag.Count -gt 1)
|
||||
# {
|
||||
# $tagIds = (Get-rCisTag -Name $Tag).Id
|
||||
# }
|
||||
# $Entity = foreach($ent in $Entity){
|
||||
# if($ent -is [string]){
|
||||
# Get-Inventory -Name $ent -ErrorAction SilentlyContinue
|
||||
# }
|
||||
# else{$ent}
|
||||
# }
|
||||
#
|
||||
# if($Entity.Count -eq 1)
|
||||
# {
|
||||
# $entMoRef = New-Object PSObject -Property @{
|
||||
# type = $Entity[0].ExtensionData.MoRef.Type
|
||||
# id = $Entity[0].ExtensionData.MoRef.Value
|
||||
# }
|
||||
# if($tag.Count -eq 1){
|
||||
# $sRest = @{
|
||||
# Method = 'Post'
|
||||
# Request = "com/vmware/cis/tagging/tag-association/id:$($tagId)?~action=attach"
|
||||
# Body = @{
|
||||
# object_id = $entMoRef
|
||||
# }
|
||||
# }
|
||||
# Invoke-vCisRest @sRest
|
||||
# }
|
||||
# elseif($Tag.Count -gt 1){
|
||||
# $sRest = @{
|
||||
# Method = 'Post'
|
||||
# Request = 'com/vmware/cis/tagging/tagassociation?~action=attach-multiple-tags-to-object'
|
||||
# Body = @{
|
||||
# object_id = $entMoRef
|
||||
# tag_ids = @($tagIds)
|
||||
# }
|
||||
# }
|
||||
# Invoke-vCisRest @sRest
|
||||
# }
|
||||
# }
|
||||
# elseif($Entity.Count -gt 1)
|
||||
# {
|
||||
# $entMorefs = $Entity | %{
|
||||
# New-Object PSObject -Property @{
|
||||
# type = $_.ExtensionData.MoRef.Type
|
||||
# id = $_.ExtensionData.MoRef.Value
|
||||
# }
|
||||
# }
|
||||
# if($tag.Count -eq 1){
|
||||
# $sRest = @{
|
||||
# Method = 'Post'
|
||||
# Request = 'com/vmware/cis/tagging/tagassociation/id:$($tagId)?~action=attach-tag-to-multiple-objects'
|
||||
# Body = @{
|
||||
# objects_ids = @($entMoRefs)
|
||||
# tag_id = $tagId
|
||||
# }
|
||||
# }
|
||||
# Invoke-vCisRest @sRest
|
||||
# }
|
||||
# elseif($Tag.Count -gt 1){
|
||||
# $tagIds | %{
|
||||
# $sRest = @{
|
||||
# Method = 'Post'
|
||||
# Request = 'com/vmware/cis/tagging/tagassociation/id:$($tagId)?~action=attach-tag-to-multiple-objects'
|
||||
# Body = @{
|
||||
# objects_ids = @($entMoRefs)
|
||||
# tag_id = $_
|
||||
# }
|
||||
# }
|
||||
# Invoke-vCisRest @sRest
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
}
|
||||
|
||||
function Remove-rCisTag{
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High', DefaultParameterSetName='Name')]
|
||||
param (
|
||||
[Parameter(Mandatory=$true, Position = 1, ValueFromPipeline = $true,ParameterSetName='Name')]
|
||||
[PSObject[]]$Tag,
|
||||
[Parameter(Mandatory=$true, Position = 1, ValueFromPipelineByPropertyName = $true,ParameterSetName='Id')]
|
||||
[String[]]$Id
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
if($PSCmdlet.ParameterSetName -eq 'Name'){
|
||||
foreach($tagObj in $Tag){
|
||||
if($tagObj -is [string]){
|
||||
$tagObj = Get-rCisTag -Name $tagObj
|
||||
}
|
||||
$sRest = @{
|
||||
Method = 'Delete'
|
||||
Request = "com/vmware/cis/tagging/tag/id:$($tagObj.Id)"
|
||||
}
|
||||
Invoke-vCisRest @sRest
|
||||
}
|
||||
}
|
||||
else{
|
||||
foreach($tagId in $Id){
|
||||
$sRest = @{
|
||||
Method = 'Delete'
|
||||
Request = "com/vmware/cis/tagging/tag/id:$($tagId)"
|
||||
}
|
||||
Invoke-vCisRest @sRest
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Remove-rCisTagCategory{
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High', DefaultParameterSetName='Name')]
|
||||
param (
|
||||
[Parameter(Mandatory=$true,Position = 1, ValueFromPipeline = $true,ParameterSetName='Name')]
|
||||
[PSObject[]]$Category,
|
||||
[Parameter(Mandatory=$true,Position = 1, ValueFromPipelineByPropertyName = $true,ParameterSetName='Id')]
|
||||
[String[]]$Id
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
if($PSCmdlet.ParameterSetName -eq 'Name'){
|
||||
foreach($catObj in $Category){
|
||||
if($catObj -is [string]){
|
||||
$catObj = Get-rCisTagCategory -Name $catObj
|
||||
}
|
||||
$sRest = @{
|
||||
Method = 'Delete'
|
||||
Request = "com/vmware/cis/tagging/category/id:$($catObj.Id)"
|
||||
}
|
||||
Invoke-vCisRest @sRest
|
||||
}
|
||||
}
|
||||
else{
|
||||
foreach($catId in $Id){
|
||||
$sRest = @{
|
||||
Method = 'Delete'
|
||||
Request = "com/vmware/cis/tagging/category/id:$($catId)"
|
||||
}
|
||||
Invoke-vCisRest @sRest
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Remove-rCisTagAssignment{
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High',DefaultParameterSetName='Assignment')]
|
||||
param (
|
||||
[Parameter(Mandatory=$true, Position = 1, ValueFromPipeline = $true,ParameterSetName='Assignment')]
|
||||
[PSObject[]]$TagAssignment,
|
||||
[Parameter(Mandatory=$true,Position = 1, ValueFromPipeline = $true,ParameterSetName='Name')]
|
||||
[string[]]$Tag,
|
||||
[Parameter(Position = 2, ParameterSetName='Name')]
|
||||
[string[]]$Category,
|
||||
[Parameter(Mandatory=$true, ValueFromPipelineByPropertyName = $true,ParameterSetName='Id')]
|
||||
[string[]]$TagId,
|
||||
[Parameter(ParameterSetName='Name')]
|
||||
[Parameter(ParameterSetName='Id')]
|
||||
[PSObject[]]$Entity
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
|
||||
switch ($PSCmdlet.ParameterSetName){
|
||||
'Name' {
|
||||
$TagAssignment = Get-rCisTagAssignment -Entity $Entity -Tag $Tag -Category $Category
|
||||
}
|
||||
'Id' {
|
||||
$tags = Get-rCisTag -Id $TagId
|
||||
$TagAssignment = Get-rCisTagAssignment -Tag $tags.Name -Entity $Entity
|
||||
}
|
||||
}
|
||||
if($TagAssignment){
|
||||
$entMoRefs = @(Get-Inventory -Name $TagAssignment.Entity -ErrorAction SilentlyContinue | %{
|
||||
New-Object PSObject -Property @{
|
||||
type = $_.ExtensionData.MoRef.Type
|
||||
id = $_.ExtensionData.MoRef.Value
|
||||
}
|
||||
})
|
||||
$tagIds = @((Get-rCisTag -Name $TagAssignment.Tag).Id)
|
||||
}
|
||||
|
||||
foreach($entMoRef in $entMoRefs){
|
||||
foreach($tId in $tagIds){
|
||||
$sRest = @{
|
||||
Method = 'Post'
|
||||
Request = "com/vmware/cis/tagging/tag-association/id:$($tId)?~action=detach"
|
||||
Body = @{
|
||||
object_id = $entMoRef
|
||||
}
|
||||
}
|
||||
Invoke-vCisRest @sRest
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Set-rCisTag{
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
|
||||
param (
|
||||
[Parameter(Mandatory=$true, Position = 1, ValueFromPipeline = $true)]
|
||||
[PSObject[]]$Tag,
|
||||
[Parameter(Position = 2)]
|
||||
[string]$Name,
|
||||
[Parameter(Position = 3)]
|
||||
[string]$Description
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
foreach($tagObj in $Tag){
|
||||
if($tagObj -is [string]){
|
||||
$tagObj = Get-rCisTag -Name $tagObj
|
||||
}
|
||||
$sRest = @{
|
||||
Method = 'Patch'
|
||||
Request = "com/vmware/cis/tagging/tag/id:$($tagObj.Id)"
|
||||
Body = @{
|
||||
update_spec = @{
|
||||
name = $Name
|
||||
description = $Description
|
||||
}
|
||||
}
|
||||
}
|
||||
Invoke-vCisRest @sRest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Set-rCisTagCategory{
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
|
||||
param (
|
||||
[Parameter(Mandatory=$true, Position = 1, ValueFromPipeline = $true)]
|
||||
[PSObject[]]$Category,
|
||||
[Parameter(Position = 2)]
|
||||
[string]$Name,
|
||||
[Parameter(Position = 3)]
|
||||
[ValidateSet('Single','Multiple')]
|
||||
[string]$Cardinality, # Only SINGLE to MULTIPLE
|
||||
# [string[]]$AddEntityType, # Does not work
|
||||
[string]$Description
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
foreach($catObj in $Category){
|
||||
if($catObj -is [string]){
|
||||
$catObj = Get-rCisTagCategory -Name $catObj
|
||||
}
|
||||
$sRest = @{
|
||||
Method = 'Patch'
|
||||
Request = "com/vmware/cis/tagging/category/id:$($catObj.Id)"
|
||||
Body = @{
|
||||
update_spec = @{
|
||||
}
|
||||
}
|
||||
}
|
||||
if($Name){
|
||||
$sRest.Body.update_spec.Add('name',$Name)
|
||||
}
|
||||
if($Description){
|
||||
$sRest.Body.update_spec.Add('description',$Description)
|
||||
}
|
||||
if($Cardinality -and $catObj.Cardinality -eq 'SINGLE'){
|
||||
$sRest.Body.update_spec.Add('cardinality',$Cardinality.ToUpper())
|
||||
}
|
||||
if($Name -or $Description -or $Cardinality){
|
||||
Invoke-vCisRest @sRest
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
79
Modules/vCenter.Alarms/New-vCenterAlarms.ps1
Normal file
79
Modules/vCenter.Alarms/New-vCenterAlarms.ps1
Normal file
@@ -0,0 +1,79 @@
|
||||
<#
|
||||
|
||||
===========================================================================
|
||||
Created by: Jason Robinson
|
||||
Created on: 05/2017
|
||||
Twitter: @jrob24
|
||||
Filename: New-vCenterAlarms.ps1
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Examples of creating alarms using vCenter.Alarm module
|
||||
#>
|
||||
|
||||
Import-Module -Name vCenter.Alarms
|
||||
|
||||
Write-Verbose -Message "Example 1 : Creating new Host CPU Usage alarm (Metric based alarm)"
|
||||
Write-Verbose -Message "Finding the metric id for 'cpu.usage.average'"
|
||||
$MetricId = (Get-MetricId -MetricGroup CPU | Where-Object -FilterScript { $_.Name -eq 'cpu.usage.average' }).Key
|
||||
Write-Verbose -Message "Creating an alarm trigger for cpu.usage.average of 90% for 15mins (Warning) & 95% for 10mins (Alert) on the HostSystem object type"
|
||||
$Trigger = New-AlarmTrigger -MetricId $MetricId -MetricOperator isAbove -ObjectType HostSystem -Yellow 90 -YellowInterval 15 -Red 95 -RedInterval 10
|
||||
Write-Verbose -Message "Creates a new alarm called 'Host CPU Usage' at the root level of vCenter"
|
||||
New-AlarmDefinition -Name "Host CPU Usage" -Description "Alarm on 95%" -Entity Datacenters -Trigger $Trigger -ActionRepeatMinutes 10
|
||||
Write-Verbose -Message "Configures the alarm to send snmp traps"
|
||||
Get-AlarmDefinition -Name "Host CPU Usage" | vSphere.Alarms\New-AlarmAction -Snmp -GreenToYellow Once -YellowToRed Repeat
|
||||
|
||||
Write-Verbose -Message "Example 2 : Creating new HA Disabled alarm (Event based alarm)"
|
||||
Write-Verbose -Message "Finding the event type for 'HA disabled for cluster'"
|
||||
$EventType = (Get-EventId | Where-Object -FilterScript { $_.Description -match 'HA disabled for cluster' }).EventType
|
||||
Write-Verbose -Message "Creating an alarm trigger for 'DasDisabledEvent' on the ClusterComputeResource object type"
|
||||
$Trigger = New-AlarmTrigger -EventType $EventType -Status Red -ObjectType ClusterComputeResource
|
||||
Write-Verbose -Message "Creates a new alarm called 'HA Disabled' at the root level of vCenter"
|
||||
New-AlarmDefinition -Name "HA Disabled" -Description "Alarm on HA" -Entity Datacenters -Trigger $Trigger -ActionRepeatMinutes 30
|
||||
Write-Verbose -Message "Configures the alarm to send an email every 30mins"
|
||||
$EmailParams = @{
|
||||
Email = $true
|
||||
To = 'helpdesk@company.com'
|
||||
Subject = 'HA Disabled'
|
||||
}
|
||||
Get-AlarmDefinition -Name "HA Disabled" | vCenter.Alarms\New-AlarmAction @EmailParams -YellowToRed Repeat
|
||||
|
||||
Write-Verbose -Message "Example 3 : Creating new Host Connection State alarm (State based alarm)"
|
||||
Write-Verbose -Message "Creating an alarm trigger for StateType of 'runtime.connectionState' on the HostSystem object type"
|
||||
$Trigger = New-AlarmTrigger -StateType runtime.connectionState -StateOperator isEqual -YellowStateCondition disconnected -RedStateCondition notResponding -ObjectType HostSystem
|
||||
Write-Verbose -Message "Creates a new alarm called 'Host Connection State' at the root level of vCenter"
|
||||
New-AlarmDefinition -Name "Host Connection State" -Description "Connection State" -Entity Datacenters -Trigger $Trigger
|
||||
Write-Verbose -Message "Configures the alarm to send an email once"
|
||||
$EmailParams = @{
|
||||
Email = $true
|
||||
To = 'helpdesk@company.com'
|
||||
Subject = 'Host Connection Lost'
|
||||
}
|
||||
Get-AlarmDefinition -Name "Host Connection State" | vCenter.Alarms\New-AlarmAction @EmailParams -YellowToRed Once
|
||||
|
||||
Write-Verbose -Message "Example 4 : Creating new Lost Storage Connectivity (Event based alarm)"
|
||||
Write-Verbose -Message "Find the event type for 'Lost Storage Connectivity'"
|
||||
Get-EventId | Where-Object -FilterScript { $_.Description -match 'Lost Storage Connectivity' }
|
||||
Write-Verbose -Message "Two results returned, we want esx not vprob"
|
||||
<#
|
||||
EventType : EventEx
|
||||
EventTypeId : esx.problem.storage.connectivity.lost
|
||||
Category : error
|
||||
Description : Lost Storage Connectivity
|
||||
FullFormat : Lost connectivity to storage device { 1 }. Path { 2 } is down. Affected datastores: { 3 }.
|
||||
vCenter : vCenter01
|
||||
|
||||
EventType : EventEx
|
||||
EventTypeId : vprob.storage.connectivity.lost
|
||||
Category : error
|
||||
Description : Lost Storage Connectivity
|
||||
FullFormat : Lost connectivity to storage device { 1 }. Path { 2 } is down. Affected datastores: { 3 }.
|
||||
vCenter : vCenter01
|
||||
#>
|
||||
Write-Verbose -Message "Since the event type is EventEx, we need both the EventType & EventTypeId to create the trigger"
|
||||
$EventType = Get-EventId | Where-Object -FilterScript { $_.EventTypeId -eq 'esx.problem.storage.connectivity.lost' }
|
||||
Write-Verbose -Message "Creating an alarm trigger for 'DasDisabledEvent' on the ClusterComputeResource object type"
|
||||
$Trigger = New-AlarmTrigger -EventType $EventType.EventType -EventTypeId $EventType.EventTypeId -Status Red -ObjectType HostSystem
|
||||
Write-Verbose -Message "Creates a new alarm called 'Lost Storage Connectivity' at the root level of vCenter"
|
||||
New-AlarmDefinition -Name "Lost Storage Connectivity" -Description "Lost Storage" -Entity Datacenters -Trigger $Trigger -ActionRepeatMinutes 5
|
||||
Write-Verbose -Message "Configures the alarm to send an snmp every 5mins"
|
||||
Get-AlarmDefinition -Name "Lost Storage Connectivity" | vCenter.Alarms\New-AlarmAction -Snmp -YellowToRed Repeat
|
||||
736
Modules/vCenter.Alarms/vCenter.Alarms.psm1
Normal file
736
Modules/vCenter.Alarms/vCenter.Alarms.psm1
Normal file
@@ -0,0 +1,736 @@
|
||||
<#
|
||||
===========================================================================
|
||||
Created by: Jason Robinson
|
||||
Created on: 05/2017
|
||||
Twitter: @jrob24
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
PowerShell Module to help with creation of vCenter Alarms
|
||||
.NOTES
|
||||
See New-vCenterAlarms.ps1 for examples of alarm creation
|
||||
|
||||
* Tested against PowerShell 5.0
|
||||
* Tested against PowerCLI 6.5.1 build 5377412
|
||||
* Tested against vCenter 6.0
|
||||
* Tested against ESXi 5.5/6.0
|
||||
#>
|
||||
|
||||
function New-AlarmDefinition {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This cmdlet creates a new alarm defintion on the specified entity in vCenter.
|
||||
.DESCRIPTION
|
||||
This cmdlet creates a new alarm defintion on the specified entity in vCenter.
|
||||
An alarm trigger is required in order to create a new alarm definition.
|
||||
They can be created by using the New-AlarmTrigger cmdlet.
|
||||
|
||||
After the alarm definition is created, if alarm actions are required use
|
||||
the cmdlet New-AlarmAction to create actions for the alarm.
|
||||
.PARAMETER Name
|
||||
Specifies the name of the alarm you want to create.
|
||||
.PARAMETER Description
|
||||
Specifies the description for the alarm.
|
||||
.PARAMETER Entity
|
||||
Specifies where to create the alarm. To create the alarm at the root
|
||||
level of vCenter use the entity 'Datacenters', otherwise specify any
|
||||
object name.
|
||||
.PARAMETER Trigger
|
||||
Specifies the alarm event, state, or metric trigger(s). The alarm
|
||||
trigger(s) are created with the New-AlarmTrigger cmdlet. For more
|
||||
information about triggers, run Get-Help New-AlarmTrigger.
|
||||
.PARAMETER Enabled
|
||||
Specifies if the alarm is enabled when it is created. If unset, the
|
||||
default value is true.
|
||||
.PARAMETER ActionRepeatMinutes
|
||||
Specifies the frequency how often the actions should repeat when an alarm
|
||||
does not change state.
|
||||
.PARAMETER ReportingFrequency
|
||||
Specifies how often the alarm is triggered, measured in minutes. A zero
|
||||
value means the alarm is allowed to trigger as often as possible. A
|
||||
nonzero value means that any subsequent triggers are suppressed for a
|
||||
period of minutes following a reported trigger.
|
||||
|
||||
If unset, the default value is 0. Allowed range is 0 - 60.
|
||||
.PARAMETER ToleranceRange
|
||||
Specifies the tolerance range for the metric triggers, measure in
|
||||
percentage. A zero value means that the alarm triggers whenever the metric
|
||||
value is above or below the specified value. A nonzero means that the
|
||||
alarm triggers only after reaching a certain percentage above or below
|
||||
the nominal trigger value.
|
||||
|
||||
If unset, the default value is 0. Allowed range is 0 - 100.
|
||||
.PARAMETER Server
|
||||
Specifies the vCenter Server system on which you want to run the cmdlet.
|
||||
If no value is passed to this parameter, the command runs on the default
|
||||
server, $DefaultVIServer. For more information about default servers,
|
||||
see the description of Connect-VIServer.
|
||||
.OUTPUTS
|
||||
VMware.Vim.ManagedObjectReference
|
||||
.NOTES
|
||||
This cmdlet requires a connection to vCenter to create the alarm action.
|
||||
.LINKS
|
||||
http://pubs.vmware.com/vsphere-6-0/topic/com.vmware.wssdk.apiref.doc/vim.alarm.AlarmSpec.html
|
||||
.EXAMPLE
|
||||
PS C:\> $trigger = New-AlarmTrigger -StateType runtime.connectionState -StateOperator isEqual -YellowStateCondition disconnected -RedStateCondition notResponding -ObjectType HostSystem
|
||||
PS C:\> New-AlarmDefinition -Name 'Host Connection' -Description 'Host Connection State Alarm -Entity Datacenters -Trigger $trigger -ActionRepeatMinutes 10
|
||||
|
||||
Type Value
|
||||
---- -----
|
||||
Alarm alarm-1801
|
||||
|
||||
This will create a host connection state alarm trigger and store it in
|
||||
the variable $trigger. Then it will create a new alarm 'Host Connection'
|
||||
on the root level of vCenter and set the action to repeat every 10 mins.
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[Alias('AlarmName')]
|
||||
[string]$Name,
|
||||
|
||||
[string]$Description,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Entity,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[VMware.Vim.AlarmExpression[]]$Trigger,
|
||||
|
||||
[boolean]$Enabled = $true,
|
||||
|
||||
[ValidateRange(0, 60)]
|
||||
[int32]$ActionRepeatMinutes,
|
||||
|
||||
[ValidateRange(0, 60)]
|
||||
[int32]$ReportingFrequency = 0,
|
||||
|
||||
[ValidateRange(0, 100)]
|
||||
[int32]$ToleranceRange = 0,
|
||||
|
||||
[string]$Server
|
||||
)
|
||||
BEGIN {
|
||||
Write-Verbose -Message "Adding parameters with default values to PSBoundParameters"
|
||||
foreach ($Key in $MyInvocation.MyCommand.Parameters.Keys) {
|
||||
$Value = Get-Variable $Key -ValueOnly -ErrorAction SilentlyContinue
|
||||
if ($Value -and !$PSBoundParameters.ContainsKey($Key)) {
|
||||
$PSBoundParameters[$Key] = $Value
|
||||
}
|
||||
}
|
||||
}
|
||||
PROCESS {
|
||||
try {
|
||||
if ($PSBoundParameters.ContainsKey('Server')) {
|
||||
$Object = Get-Inventory -Name $PSBoundParameters['Entity'] -ErrorAction Stop -Server $PSBoundParameters['Server']
|
||||
$AlarmMgr = Get-View AlarmManager -ErrorAction Stop -Server $PSBoundParameters['Server']
|
||||
} else {
|
||||
$Object = Get-Inventory -Name $PSBoundParameters['Entity'] -ErrorAction Stop -Server $global:DefaultVIServer
|
||||
$AlarmMgr = Get-View AlarmManager -ErrorAction Stop -Server $global:DefaultVIServer
|
||||
}
|
||||
|
||||
if ($PSCmdlet.ShouldProcess($global:DefaultVIServer, "Create alarm $($PSBoundParameters['Name'])")) {
|
||||
$Alarm = New-Object -TypeName VMware.Vim.AlarmSpec
|
||||
$Alarm.Name = $PSBoundParameters['Name']
|
||||
$Alarm.Description = $PSBoundParameters['Description']
|
||||
$Alarm.Enabled = $PSBoundParameters['Enabled']
|
||||
$Alarm.Expression = New-Object -TypeName VMware.Vim.OrAlarmExpression
|
||||
$Alarm.Expression.Expression += $PSBoundParameters['Trigger']
|
||||
$Alarm.Setting = New-Object -TypeName VMware.Vim.AlarmSetting
|
||||
$Alarm.Setting.ReportingFrequency = $PSBoundParameters['ReportingFrequency'] * 60
|
||||
$Alarm.Setting.ToleranceRange = $PSBoundParameters['ToleranceRange'] * 100
|
||||
$Alarm.ActionFrequency = $PSBoundParameters['ActionRepeatMinutes'] * 60
|
||||
$AlarmMgr.CreateAlarm($Object.Id, $Alarm)
|
||||
}
|
||||
} catch {
|
||||
$PSCmdlet.ThrowTerminatingError($_)
|
||||
}
|
||||
}
|
||||
} #End of New-AlarmDefinition function
|
||||
|
||||
function New-AlarmAction {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This cmdlet creates an alarm action on the specified alarm definition.
|
||||
.DESCRIPTION
|
||||
This cmdlet creates an alarm action on the specified alarm definition.
|
||||
This cmdlet differs from the VMware PowerCLI New-AlarmAction cmdlet as it
|
||||
will create the transitions of the alarm state. It requires an alarm
|
||||
action and at least one transition to be specified.
|
||||
|
||||
The transition indicates when the action executes and if it repeats.
|
||||
There are only four acceptable transitions: green to yellow, yellow to
|
||||
red, red to yellow, and yellow to green. At least one pair must be
|
||||
specified or the results will be an invalid.
|
||||
|
||||
If an alarm action already exists on the alarm definition, it will be
|
||||
overwritten if the same alarm action is specified. For example if the
|
||||
alarm definition already has an alarm action of Snmp on the transition
|
||||
of green to yellow and the cmdlet is used to create a new action of
|
||||
Snmp on the transition of yellow to red, it will overwrite the existing
|
||||
action and transition. The end result will be one Snmp action on the
|
||||
transition of yellow to red. If you want the old to transition to remain
|
||||
both should be specified during the usage of the cmdlet.
|
||||
.PARAMETER AlarmDefinition
|
||||
Specifies the alarm definition for which you want to configure actions.
|
||||
The alarm definition can be retreived by using the Get-AlarmDefinition
|
||||
cmdlet.
|
||||
.PARAMETER Snmp
|
||||
Indicates that a SNMP message is sent when the alarm is activated.
|
||||
.PARAMETER Email
|
||||
Indicates that when the alarm is activated, the system sends an email
|
||||
message to the specified address. Use the Subject, To, CC, and Body
|
||||
parameters to customize the alarm message.
|
||||
.PARAMETER To
|
||||
Specifies the email address to which you want to send a message.
|
||||
.PARAMETER Cc
|
||||
Specifies the email address you want to add to the CC field of the email
|
||||
message.
|
||||
.PARAMETER Subject
|
||||
Specifies a subject for the email address message you want to send.
|
||||
.PARAMETER Body
|
||||
Specifies the text of the email message.
|
||||
.PARAMETER GreenToYellow
|
||||
Specifies the alarm action for the green to yellow transition. Allowed
|
||||
values are 'Once' and 'Repeat'. If parameter is not set transition will
|
||||
remain unset.
|
||||
.PARAMETER YellowToRed
|
||||
Specifies the alarm action for the yellow to red transition. Allowed
|
||||
values are 'Once' and 'Repeat'. If parameter is not set transition will
|
||||
remain unset.
|
||||
.PARAMETER RedToYellow
|
||||
Specifies the alarm action for the red to yellow transition. Allowed
|
||||
values are 'Once' and 'Repeat'. If parameter is not set transition will
|
||||
remain unset.
|
||||
.PARAMETER YellowToGreen
|
||||
Specifies the alarm action for the yellow to green transition. Allowed
|
||||
values are 'Once' and 'Repeat'. If parameter is not set transition will
|
||||
remain unset.
|
||||
.NOTES
|
||||
This cmdlet requires a connection to vCenter to create the alarm action.
|
||||
|
||||
When using this cmdlet specify the Module-Qualified cmdlet name to avoid
|
||||
using the New-AlarmAction cmdlet with VMware PowerCLI.
|
||||
.EXAMPLE
|
||||
PS C:\> vCenter.Alarms\New-AlarmAction -AlarmDefinition (Get-AlarmDefintion "Host CPU Usage") -Snmp -YellowToRed Repeat
|
||||
|
||||
This will create an Snmp alarm action on the "Host CPU Usage" alarm
|
||||
transition of yellow to red. The alarm action will also repeat, as per
|
||||
the action frequency defined on the alarm.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-AlarmDefintion "Cluster HA Status" | vCenter.Alarms\New-AlarmAction -Email -To helpdesk@company.com -GreenToYellow Once -YellowToRed Once
|
||||
|
||||
This will create an Email alarm action on the "Cluster HA Status" alarm
|
||||
transition of green to yellow and yellow to red. The alarm action will
|
||||
send an email to helpdesk@company.com one time per transition.
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]
|
||||
param (
|
||||
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Alarm.AlarmDefinition]$AlarmDefinition,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'Snmp')]
|
||||
[switch]$Snmp,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'Email')]
|
||||
[switch]$Email,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'Email')]
|
||||
[string[]]$To,
|
||||
|
||||
[Parameter(ParameterSetName = 'Email')]
|
||||
[string[]]$Cc,
|
||||
|
||||
[Parameter(ParameterSetName = 'Email')]
|
||||
[string]$Subject,
|
||||
|
||||
[Parameter(ParameterSetName = 'Email')]
|
||||
[string]$Body,
|
||||
|
||||
[ValidateSet('Once', 'Repeat')]
|
||||
[string]$GreenToYellow,
|
||||
|
||||
[ValidateSet('Once', 'Repeat')]
|
||||
[string]$YellowToRed,
|
||||
|
||||
[ValidateSet('Once', 'Repeat')]
|
||||
[string]$RedToYellow,
|
||||
|
||||
[ValidateSet('Once', 'Repeat')]
|
||||
[string]$YellowToGreen
|
||||
)
|
||||
|
||||
BEGIN {
|
||||
}
|
||||
PROCESS {
|
||||
try {
|
||||
$AlarmView = Get-View -Id $PSBoundParameters['AlarmDefinition'].Id -Server ($PSBoundParameters['AlarmDefinition'].Uid.Split('@:')[1])
|
||||
$Alarm = New-Object -TypeName VMware.Vim.AlarmSpec
|
||||
$Alarm.Name = $AlarmView.Info.Name
|
||||
$Alarm.Description = $AlarmView.Info.Description
|
||||
$Alarm.Enabled = $AlarmView.Info.Enabled
|
||||
$Alarm.ActionFrequency = $AlarmView.Info.ActionFrequency
|
||||
$Alarm.Action = New-Object VMware.Vim.GroupAlarmAction
|
||||
$Trigger = New-Object VMware.Vim.AlarmTriggeringAction
|
||||
|
||||
Write-Verbose -Message "Defining alarm actions"
|
||||
if ($PSCmdlet.ParameterSetName -eq 'Snmp') {
|
||||
$Trigger.Action = New-Object -TypeName VMware.Vim.SendSNMPAction
|
||||
} elseif ($PSCmdlet.ParameterSetName -eq 'Email') {
|
||||
$Trigger.Action = New-Object -TypeName VMware.Vim.SendEmailAction
|
||||
$Trigger.Action.ToList = $PSBoundParameters['To'].GetEnumerator() | ForEach-Object -Process {
|
||||
"$_;"
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('Cc')) {
|
||||
$Trigger.Action.CcList = $PSBoundParameters['Cc'].GetEnumerator() | ForEach-Object -Process {
|
||||
"$_;"
|
||||
}
|
||||
} else {
|
||||
$Trigger.Action.CcList = $null
|
||||
}
|
||||
$Trigger.Action.Subject = $PSBoundParameters['Subject']
|
||||
$Trigger.Action.Body = $PSBoundParameters['Body']
|
||||
}
|
||||
|
||||
Write-Verbose -Message "Defining alarm transitions"
|
||||
if ($PSBoundParameters.ContainsKey('GreenToYellow')) {
|
||||
$Trans1 = New-Object -TypeName VMware.Vim.AlarmTriggeringActionTransitionSpec
|
||||
$Trans1.StartState = 'green'
|
||||
$Trans1.FinalState = 'yellow'
|
||||
if ($PSBoundParameters['GreenToYellow'] -eq 'Repeat') {
|
||||
$Trans1.Repeats = $true
|
||||
}
|
||||
$Trigger.TransitionSpecs += $Trans1
|
||||
}
|
||||
|
||||
if ($PSBoundParameters.ContainsKey('YellowToRed')) {
|
||||
$Trans2 = New-Object -TypeName VMware.Vim.AlarmTriggeringActionTransitionSpec
|
||||
$Trans2.StartState = 'yellow'
|
||||
$Trans2.FinalState = 'red'
|
||||
if ($PSBoundParameters['YellowToRed'] -eq 'Repeat') {
|
||||
$Trans2.Repeats = $true
|
||||
} else {
|
||||
$Trans2.Repeats = $false
|
||||
}
|
||||
$Trigger.TransitionSpecs += $Trans2
|
||||
}
|
||||
|
||||
if ($PSBoundParameters.ContainsKey('RedToYellow')) {
|
||||
$Trans3 = New-Object -TypeName VMware.Vim.AlarmTriggeringActionTransitionSpec
|
||||
$Trans3.StartState = 'red'
|
||||
$Trans3.FinalState = 'yellow'
|
||||
if ($PSBoundParameters['RedToYellow'] -eq 'Repeat') {
|
||||
$Trans3.Repeats = $true
|
||||
} else {
|
||||
$Trans3.Repeats = $false
|
||||
}
|
||||
$Trigger.TransitionSpecs += $Trans3
|
||||
}
|
||||
|
||||
if ($PSBoundParameters.ContainsKey('YellowToGreen')) {
|
||||
$Trans4 = New-Object -TypeName VMware.Vim.AlarmTriggeringActionTransitionSpec
|
||||
$Trans4.StartState = 'yellow'
|
||||
$Trans4.FinalState = 'green'
|
||||
if ($PSBoundParameters['YellowToGreen'] -eq 'Repeat') {
|
||||
$Trans4.Repeats = $true
|
||||
} else {
|
||||
$Trans4.Repeats = $false
|
||||
}
|
||||
$Trigger.TransitionSpecs += $Trans4
|
||||
}
|
||||
|
||||
$Alarm.Action.Action += $Trigger
|
||||
$Alarm.Expression = New-Object -TypeName VMware.Vim.OrAlarmExpression
|
||||
$Alarm.Expression.Expression += $AlarmView.Info.Expression.Expression
|
||||
$Alarm.Setting += $AlarmView.Info.Setting
|
||||
$AlarmView.ReconfigureAlarm($Alarm)
|
||||
} catch {
|
||||
$PSCmdlet.ThrowTerminatingError($_)
|
||||
}
|
||||
}
|
||||
} #End of New-AlarmAction function
|
||||
|
||||
function New-AlarmTrigger {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This cmdlet creates a vCenter event, state, or metric alarm trigger.
|
||||
.DESCRIPTION
|
||||
This cmdlet creates a vCenter event, state, or metric alarm trigger.
|
||||
The trigger is used with the New-AlarmDefinition cmdlet to create a new
|
||||
alarm in vCenter. This cmdlet will only create one alarm trigger. If more
|
||||
triggers are required store the triggers in an array.
|
||||
.PARAMETER EventType
|
||||
Specifies the type of the event to trigger on. The event types can be
|
||||
discovered by using the Get-EventId cmdlet. If the the event type is
|
||||
'EventEx' or 'ExtendedEvent' the EventTypeId parameter is required.
|
||||
.PARAMETER EventTypeId
|
||||
Specifies the id of the event type. Only used when the event type is an
|
||||
'EventEx' or 'ExtendedEvent'.
|
||||
.PARAMETER Status
|
||||
Specifies the status of the event. Allowed values are green, yellow, or
|
||||
red.
|
||||
.PARAMETER StateType
|
||||
Specifies the state type to trigger on. Allowed values are
|
||||
runtime.powerstate (HostSystem), summary.quickStats.guestHeartbeatStatus
|
||||
(VirtualMachine), or runtime.connectionState (VirtualMachine).
|
||||
.PARAMETER StateOperator
|
||||
Specifies the operator condition on the target state. Allowed values are
|
||||
'isEqual' or 'isUnequal'.
|
||||
.PARAMETER YellowStateCondition
|
||||
Specifies the yellow state condition. When creating a state alarm
|
||||
trigger at least one condition must be specified for a valid trigger to
|
||||
be created. If the parameter is not set, the yellow condition is unset.
|
||||
.PARAMETER RedStateCondition
|
||||
Specifies the red state condition. When creating a state alarm trigger
|
||||
at least one condition must be specified for a valid trigger to be
|
||||
created. If the parameter is not set, the red condition is unset.
|
||||
.PARAMETER MetricId
|
||||
Specifies the id of the metric to trigger on. The metric ids can be
|
||||
discovered by using the Get-MetricId cmdlet.
|
||||
.PARAMETER MetricOperator
|
||||
Specifies the operator condition on the target metric. Allowed values
|
||||
are 'isAbove' or 'isBelow'.
|
||||
.PARAMETER Yellow
|
||||
Specifies the threshold value that triggers a yellow status. Allowed
|
||||
range is 1% - 100%.
|
||||
.PARAMETER YellowInterval
|
||||
Specifies the time interval in minutes for which the yellow condition
|
||||
must be true before the yellow status is triggered. If unset, the yellow
|
||||
status is triggered immediately when the yellow condition becomes true.
|
||||
.PARAMETER Red
|
||||
Specifies the threshold value that triggers a red status. Allowed range
|
||||
is 1% - 100%.
|
||||
.PARAMETER RedInterval
|
||||
Specifies the time interval in minutes for which the red condition must
|
||||
be true before the red status is triggered. If unset, the red status is
|
||||
triggered immediately when the red condition becomes true.
|
||||
.PARAMETER ObjectType
|
||||
Specifies the type of object on which the event is logged, the object
|
||||
type containing the state condition or the type of object containing the
|
||||
metric.
|
||||
|
||||
When creating a state alarm trigger the only acceptable values are
|
||||
'HostSystem' or 'VirtualMachine'. The supported state types for each object
|
||||
are as follows:
|
||||
VirtualMachine type: runtime.powerState or summary.quickStats.guestHeartbeatStatus
|
||||
HostSystem type: runtime.connectionState
|
||||
.OUTPUTS
|
||||
(Event|State|Metric)AlarmExpression
|
||||
.NOTES
|
||||
This cmdlet requires the PowerCLI module to be imported.
|
||||
.LINK
|
||||
Event Alarm Trigger
|
||||
http://pubs.vmware.com/vsphere-6-0/topic/com.vmware.wssdk.apiref.doc/vim.alarm.EventAlarmExpression.html
|
||||
|
||||
State Alarm Trigger
|
||||
http://pubs.vmware.com/vsphere-6-0/topic/com.vmware.wssdk.apiref.doc/vim.alarm.StateAlarmExpression.html
|
||||
|
||||
Metric Alarm Trigger
|
||||
http://pubs.vmware.com/vsphere-6-0/topic/com.vmware.wssdk.apiref.doc/vim.alarm.MetricAlarmExpression.html
|
||||
.EXAMPLE
|
||||
PS C:\> New-AlarmTrigger -EventType "DasDisabledEvent" -Status Red -ObjectType ClusterComputeResource
|
||||
|
||||
Comparisons :
|
||||
EventType : DasDisabledEvent
|
||||
ObjectType : ClusterComputeResource
|
||||
Status : red
|
||||
|
||||
Creates an event trigger on 'DasDisabledEvent' (HA Disabled) with a
|
||||
status on 'Red'. The object type is a ClusterComputerResource because
|
||||
this event occurs at a cluster level.
|
||||
.EXAMPLE
|
||||
PS C:\> New-AlarmTrigger -MetricId (Get-MetricId | Where Name -EQ 'cpu.usage.average').Key -Operator isAbove -Yellow 90 -YellowInterval 30 -Red 98 -RedInterval 15 -ObjectType HostSytem
|
||||
|
||||
Operator : isAbove
|
||||
Type : HostSytem
|
||||
Metric : VMware.Vim.PerfMetricId
|
||||
Yellow : 9000
|
||||
YellowInterval : 30
|
||||
Red : 9800
|
||||
RedInterval : 15
|
||||
|
||||
Creates a trigger on the 'cpu.usage.average' metric where the warning
|
||||
condition must be above 90% for 30mins and the alert condition must be
|
||||
above 98% for 15mins. The object type is a HostSystem.
|
||||
.EXAMPLE
|
||||
PS C:\temp> New-AlarmTrigger -StateType runtime.connectionState -StateOperator isEqual -YellowStateCondition Disconnected -RedStateCondition notResponding -ObjectType HostSystem
|
||||
|
||||
Operator : isEqual
|
||||
Type : HostSystem
|
||||
StatePath : runtime.connectionState
|
||||
Yellow : Disconnected
|
||||
Red : notResponding
|
||||
|
||||
Creates a trigger on the 'runtime.connectionState' condition where the
|
||||
warning condition is 'disconnected' and the alert condition is
|
||||
'notResponding'. The object type is a HostSystem.
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]
|
||||
param (
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'Event')]
|
||||
[string]$EventType,
|
||||
|
||||
[Parameter(ParameterSetName = 'Event')]
|
||||
[string]$EventTypeId,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'Event')]
|
||||
[ValidateSet('Green', 'Yellow', 'Red')]
|
||||
[string]$Status,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'State')]
|
||||
[ValidateSet('runtime.powerState', 'summary.quickStats.guestHeartbeatStatus', 'runtime.connectionState')]
|
||||
[string]$StateType,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'State')]
|
||||
[VMware.Vim.StateAlarmOperator]$StateOperator,
|
||||
|
||||
[Parameter(ParameterSetName = 'State')]
|
||||
[ValidateSet('disconnected', 'notResponding', 'connected', 'noHeartbeat', 'intermittentHeartbeat', 'poweredOn', 'poweredOff', 'suspended')]
|
||||
[string]$YellowStateCondition,
|
||||
|
||||
[Parameter(ParameterSetName = 'State')]
|
||||
[ValidateSet('disconnected', 'notResponding', 'connected', 'noHeartbeat', 'intermittentHeartbeat', 'poweredOn', 'poweredOff', 'suspended')]
|
||||
[string]$RedStateCondition,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'Metric')]
|
||||
[string]$MetricId,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'Metric')]
|
||||
[VMware.Vim.MetricAlarmOperator]$MetricOperator,
|
||||
|
||||
[Parameter(ParameterSetName = 'Metric')]
|
||||
[ValidateRange(1, 100)]
|
||||
[int32]$Yellow,
|
||||
|
||||
[Parameter(ParameterSetName = 'Metric')]
|
||||
[ValidateRange(1, 90)]
|
||||
[int32]$YellowInterval,
|
||||
|
||||
[Parameter(ParameterSetName = 'Metric')]
|
||||
[ValidateRange(1, 100)]
|
||||
[int32]$Red,
|
||||
|
||||
[Parameter(ParameterSetName = 'Metric')]
|
||||
[ValidateRange(1, 90)]
|
||||
[int32]$RedInterval,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateSet('ClusterComputeResource', 'Datacenter', 'Datastore', 'DistributedVirtualSwitch', 'HostSystem', 'Network', 'ResourcePool', 'VirtualMachine')]
|
||||
[string]$ObjectType
|
||||
)
|
||||
try {
|
||||
if ($PSCmdlet.ShouldProcess("vCenter alarm", "Create $($PSCmdlet.ParameterSetName) trigger")) {
|
||||
if ($PSCmdlet.ParameterSetName -eq 'Event') {
|
||||
$Expression = New-Object -TypeName VMware.Vim.EventAlarmExpression
|
||||
$Expression.EventType = $PSBoundParameters['EventType']
|
||||
if ($PSBoundParameters.ContainsKey('EventTypeId')) {
|
||||
$Expression.EventTypeId = $PSBoundParameters['EventTypeId']
|
||||
}
|
||||
$Expression.ObjectType = $PSBoundParameters['ObjectType']
|
||||
$Expression.Status = $PSBoundParameters['Status']
|
||||
$Expression
|
||||
} elseif ($PSCmdlet.ParameterSetName -eq 'Metric') {
|
||||
$Expression = New-Object -TypeName VMware.Vim.MetricAlarmExpression
|
||||
$Expression.Metric = New-Object -TypeName VMware.Vim.PerfMetricId
|
||||
$Expression.Metric.CounterId = $PSBoundParameters['MetricId']
|
||||
$Expression.Metric.Instance = ""
|
||||
$Expression.Operator = $PSBoundParameters['MetricOperator']
|
||||
$Expression.Red = ($PSBoundParameters['Red'] * 100)
|
||||
$Expression.RedInterval = ($PSBoundParameters['RedInterval'] * 60)
|
||||
$Expression.Yellow = ($PSBoundParameters['Yellow'] * 100)
|
||||
$Expression.YellowInterval = ($PSBoundParameters['YellowInterval'] * 60)
|
||||
$Expression.Type = $PSBoundParameters['ObjectType']
|
||||
$Expression
|
||||
} elseif ($PSCmdlet.ParameterSetName -eq 'State') {
|
||||
$Expression = New-Object -TypeName VMware.Vim.StateAlarmExpression
|
||||
$Expression.Operator = $PSBoundParameters['StateOperator']
|
||||
$Expression.Type = $PSBoundParameters['ObjectType']
|
||||
$Expression.StatePath = $PSBoundParameters['StateType']
|
||||
|
||||
if ($PSBoundParameters.ContainsKey('RedStateCondition')) {
|
||||
if ($PSBoundParameters['RedStateCondition'] -eq 'intermittentHeartbeat') {
|
||||
$Expression.Red = 'yellow'
|
||||
} elseif ($PSBoundParameters['RedStateCondition'] -eq 'noHeartbeat') {
|
||||
$Expression.Red = 'red'
|
||||
} else {
|
||||
$Expression.Red = $PSBoundParameters['RedStateCondition']
|
||||
}
|
||||
}
|
||||
|
||||
if ($PSBoundParameters.ContainsKey('YellowStateCondition')) {
|
||||
if ($PSBoundParameters['YellowStateCondition'] -eq 'intermittentHeartbeat') {
|
||||
$Expression.Yellow = 'yellow'
|
||||
} elseif ($PSBoundParameters['YellowStateCondition'] -eq 'noHeartbeat') {
|
||||
$Expression.Yellow = 'red'
|
||||
} else {
|
||||
$Expression.Yellow = $PSBoundParameters['YellowStateCondition']
|
||||
}
|
||||
}
|
||||
$Expression
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
$PSCmdlet.ThrowTerminatingError($_)
|
||||
}
|
||||
} #End of New-AlarmTrigger function
|
||||
|
||||
function Get-MetricId {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This cmdlet collects all of the available metrics from vCenter.
|
||||
.DESCRIPTION
|
||||
This cmdlet collects all of the available metrics from vCenter. It will
|
||||
provide the metric name, key, stats level, and summary of the metric.
|
||||
The information can be used to identify the available metrics on vCenter
|
||||
as well as gathering the metric key needed for configuring an alarm.
|
||||
|
||||
The metric keys are unique across vCenters. If you are connected to
|
||||
more than one vCenter metrics from each vCenter will be generated. A
|
||||
vCenter property is available to help determine the correct metric key
|
||||
on a given vCenter. This is extrememly useful when trying to create
|
||||
a metric based vCenter alarm.
|
||||
.PARAMETER MetricGroup
|
||||
Specifies the name of the metric group you would like to see. Allowed
|
||||
values are 'CPU', 'Mem', 'Disk', 'Net', and 'Datastore'.
|
||||
.OUTPUTS
|
||||
System.Management.Automation.PSCustomObject
|
||||
.NOTES
|
||||
This cmdlet requires a connection to vCenter to collect metric data.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-MetricId -MetricGroup Mem
|
||||
|
||||
Name : mem.usage.none
|
||||
Key : 23
|
||||
Level : 4
|
||||
Summary : Memory usage as percentage of total configured or available memory
|
||||
vCenter : vCenter01
|
||||
|
||||
Name : mem.usage.average
|
||||
Key : 24
|
||||
Level : 1
|
||||
Summary : Memory usage as percentage of total configured or available memory
|
||||
vCenter : vCenter01
|
||||
|
||||
Name : mem.usage.minimum
|
||||
Key : 25
|
||||
Level : 4
|
||||
Summary : Memory usage as percentage of total configured or available memory
|
||||
vCenter : vCenter01
|
||||
.....
|
||||
|
||||
Collects all of the available memory metrics on the connected vCenter.
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[ValidateSet('CPU', 'Mem', 'Disk', 'Net', 'Datastore')]
|
||||
[string]$MetricGroup
|
||||
)
|
||||
|
||||
foreach ($Mgr in (Get-View PerformanceManager-PerfMgr)) {
|
||||
$vCenter = $Mgr.Client.ServiceUrl.Split('/')[2]
|
||||
if ($PSBoundParameters.ContainsKey('MetricGroup')) {
|
||||
$Metrics += $Mgr.PerfCounter | Where-Object -FilterScript {
|
||||
$_.GroupInfo.Key -eq $PSBoundParameters['MetricGroup']
|
||||
}
|
||||
} else {
|
||||
$Metrics += $Mgr.PerfCounter
|
||||
}
|
||||
|
||||
$Metrics | ForEach-Object -Process {
|
||||
[pscustomobject] @{
|
||||
Name = $_.GroupInfo.Key + "." + $_.NameInfo.key + "." + $_.RollupType
|
||||
Key = $_.Key
|
||||
Level = $_.Level
|
||||
Summary = $_.NameInfo.Summary
|
||||
vCenter = $vCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
} #End of Get-MetricId function
|
||||
|
||||
function Get-EventId {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This cmdlet collects all of the available events from vCenter.
|
||||
.DESCRIPTION
|
||||
This cmdlet collects all of the available events from vCenter. It will
|
||||
provide the event type, event type id (if applicable), category,
|
||||
description, and summary of the event. The information can be used to
|
||||
identify the available events on vCenter as well as gathering the event
|
||||
type and event type id (if applicable) required for configuring an alarm.
|
||||
|
||||
If the event type is 'EventEx' or 'ExtendedEvent' both the event type
|
||||
and event type id will be required to create a new event based vCenter
|
||||
alarm.
|
||||
|
||||
The event types can be unique across vCenters. If you are connected to
|
||||
more than one vCenter events from each vCenter will be generated. A
|
||||
vCenter property is available to help determine the correct event type
|
||||
on a given vCenter. This is extrememly useful when trying to create
|
||||
a event based vCenter alarm.
|
||||
.PARAMETER Category
|
||||
Specifies the name of the event category you would like to see. Allowed
|
||||
values are 'info', 'warning', 'error', and 'user'.
|
||||
.OUTPUTS
|
||||
System.Management.Automation.PSCustomObject
|
||||
.NOTES
|
||||
This cmdlet requires a connection to vCenter to collect event data.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-EventId -Category Error
|
||||
|
||||
EventType : ExtendedEvent
|
||||
EventTypeId : ad.event.ImportCertFailedEvent
|
||||
Category : error
|
||||
Description : Import certificate failure
|
||||
FullFormat : Import certificate failed.
|
||||
vCenter : vCenter01
|
||||
|
||||
EventType : ExtendedEvent
|
||||
EventTypeId : ad.event.JoinDomainFailedEvent
|
||||
Category : error
|
||||
Description : Join domain failure
|
||||
FullFormat : Join domain failed.
|
||||
vCenter : vCenter01
|
||||
|
||||
EventType : ExtendedEvent
|
||||
EventTypeId : ad.event.LeaveDomainFailedEvent
|
||||
Category : error
|
||||
Description : Leave domain failure
|
||||
FullFormat : Leave domain failed.
|
||||
vCenter : vCenter01
|
||||
.....
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[VMware.Vim.EventCategory]$Category
|
||||
)
|
||||
|
||||
foreach ($Mgr in (Get-View EventManager)) {
|
||||
$vCenter = $Mgr.Client.ServiceUrl.Split('/')[2]
|
||||
if ($PSBoundParameters.ContainsKey('Category')) {
|
||||
$Events += $Mgr.Description.EventInfo | Where-Object -FilterScript {
|
||||
$_.Category -eq $PSBoundParameters['Category']
|
||||
}
|
||||
} else {
|
||||
$Events += $Mgr.Description.EventInfo
|
||||
}
|
||||
|
||||
$Events | ForEach-Object -Process {
|
||||
$Hash = [ordered]@{}
|
||||
$Hash.Add('EventType', $_.Key)
|
||||
if ($_.Key -eq 'ExtendedEvent' -or $_.Key -eq 'EventEx') {
|
||||
$Hash.Add('EventTypeId', $_.FullFormat.Split('|')[0])
|
||||
}
|
||||
$Hash.Add('Category', $_.Category)
|
||||
$Hash.Add('Description', $_.Description)
|
||||
if ($Hash['EventType'] -eq 'ExtendedEvent' -or $Hash['EventType'] -eq 'EventEx') {
|
||||
$Hash.Add('FullFormat', $_.FullFormat.Split('|')[1])
|
||||
} else {
|
||||
$Hash.Add('FullFormat', $_.FullFormat)
|
||||
}
|
||||
$Hash.Add('vCenter', $vCenter)
|
||||
New-Object -TypeName System.Management.Automation.PSObject -Property $Hash
|
||||
}
|
||||
}
|
||||
} #End of Get-EventId function
|
||||
475
Modules/vCenterManualMigration/vCenterManualMigration.psm1
Normal file
475
Modules/vCenterManualMigration/vCenterManualMigration.psm1
Normal file
@@ -0,0 +1,475 @@
|
||||
Function Export-DRSRules {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 11/21/2017
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Export DRS Rules to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.DESCRIPTION
|
||||
Export DRS Rules to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.EXAMPLE
|
||||
Export-DRSRules -Path C:\Users\primp\Desktop\VMworld2017 -Cluster Windows-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$false)][String]$Path,
|
||||
[Parameter(Mandatory=$true)][String]$Cluster
|
||||
)
|
||||
|
||||
$rules = Get-Cluster -Name $Cluster | Get-DrsRule
|
||||
|
||||
$results = @()
|
||||
foreach ($rule in $rules) {
|
||||
$vmNames = @()
|
||||
$vmIds = $rule.VMIds
|
||||
|
||||
# Reconstruct MoRef ID to VM Object to get Name
|
||||
foreach ($vmId in $vmIds) {
|
||||
$vm = New-Object VMware.Vim.ManagedObjectReference
|
||||
$vm.Type = "VirtualMachine"
|
||||
$vm.Value = ($vmId -replace "VirtualMachine-","")
|
||||
$vmView = Get-View $vm
|
||||
$vmNames += $vmView.name
|
||||
}
|
||||
|
||||
$rulesObject = [pscustomobject] @{
|
||||
Name = $rule.ExtensionData.Name;
|
||||
Type = $rule.Type; #VMAffinity = 1, VMAntiAffinity = 0
|
||||
Enabled = $rule.Enabled;
|
||||
Mandatory = $rule.ExtensionData.Mandatory
|
||||
VM = $vmNames
|
||||
}
|
||||
$results+=$rulesObject
|
||||
}
|
||||
if($Path) {
|
||||
$fullPath = $Path + "\DRSRules.json"
|
||||
Write-Host -ForegroundColor Green "Exporting DRS Rules to $fullpath ..."
|
||||
$results | ConvertTo-Json | Out-File $fullPath
|
||||
} else {
|
||||
$results | ConvertTo-Json
|
||||
}
|
||||
}
|
||||
|
||||
Function Import-DRSRules {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 11/21/2017
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Import DRS Rules from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.DESCRIPTION
|
||||
Import DRS Rules from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.EXAMPLE
|
||||
Import-DRSRules -Path C:\Users\primp\Desktop\VMworld2017 -Cluster Windows-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$Path,
|
||||
[Parameter(Mandatory=$true)][String]$Cluster
|
||||
)
|
||||
|
||||
Get-DrsRule -Cluster $cluster | Remove-DrsRule -Confirm:$false | Out-Null
|
||||
|
||||
$DRSRulesFilename = "/DRSRules.json"
|
||||
$fullPath = $Path + $DRSRulesFilename
|
||||
$json = Get-Content -Raw $fullPath | ConvertFrom-Json
|
||||
|
||||
foreach ($line in $json) {
|
||||
$vmArr = @()
|
||||
$vmNames = $line.vm
|
||||
foreach ($vmName in $vmNames) {
|
||||
$vmView = Get-VM -Name $vmName
|
||||
$vmArr+=$vmView
|
||||
}
|
||||
New-DrsRule -Name $line.name -Enabled $line.Enabled -Cluster (Get-Cluster -Name $Cluster) -KeepTogether $line.Type -VM $vmArr
|
||||
}
|
||||
}
|
||||
|
||||
Function Export-DRSClusterGroup {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 11/21/2017
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Export DRS Cluster Group Rules to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.DESCRIPTION
|
||||
Export DRS Cluster Group Rules to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.EXAMPLE
|
||||
Export-DRSClusterGroup -Path C:\Users\primp\Desktop\VMworld2017 -Cluster Windows-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$false)][String]$Path,
|
||||
[Parameter(Mandatory=$true)][String]$Cluster
|
||||
)
|
||||
|
||||
$rules = Get-Cluster -Name $Cluster | Get-DrsClusterGroup
|
||||
|
||||
$results = @()
|
||||
foreach ($rule in $rules) {
|
||||
$rulesObject = [pscustomobject] @{
|
||||
Name = $rule.ExtensionData.Name;
|
||||
Type = $rule.GroupType; #VMType = 1, HostType = 0
|
||||
Member = $rule.Member
|
||||
}
|
||||
$results+=$rulesObject
|
||||
}
|
||||
if($Path) {
|
||||
$fullPath = $Path + "\DRSClusterGroupRules.json"
|
||||
Write-Host -ForegroundColor Green "Exporting DRS Cluster Group Rules to $fullpath ..."
|
||||
$results | ConvertTo-Json | Out-File $fullPath
|
||||
} else {
|
||||
$results | ConvertTo-Json
|
||||
}
|
||||
}
|
||||
|
||||
Function Import-DRSClusterClusterGroup {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 11/21/2017
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Import DRS Cluster Group Rules from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.DESCRIPTION
|
||||
Import DRS Cluster Group Rules from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.EXAMPLE
|
||||
Import-DRSClusterClusterGroup -Path C:\Users\primp\Desktop\VMworld2017 -Cluster Windows-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$Path,
|
||||
[Parameter(Mandatory=$true)][String]$Cluster
|
||||
)
|
||||
|
||||
$DRSClusterGroupRulesFilename = "\DRSClusterGroupRules.json"
|
||||
$fullPath = $Path + $DRSClusterGroupRulesFilename
|
||||
$json = Get-Content -Raw $fullPath | ConvertFrom-Json
|
||||
|
||||
foreach ($line in $json) {
|
||||
$memberArr = @()
|
||||
$members = $line.member
|
||||
|
||||
# VMHost Group
|
||||
if($line.Type -eq 0) {
|
||||
foreach ($member in $members) {
|
||||
$memberView = Get-VMhost -Name $member
|
||||
$memberArr+=$memberView
|
||||
}
|
||||
New-DrsClusterGroup -Name $line.name -Cluster (Get-Cluster -Name $Cluster) -VMhost $memberArr
|
||||
# VM Group
|
||||
} else {
|
||||
foreach ($member in $members) {
|
||||
$memberView = Get-VM -Name $member
|
||||
$memberArr+=$memberView
|
||||
}
|
||||
New-DrsClusterGroup -Name $line.name -Cluster (Get-Cluster -Name $Cluster) -VM $memberArr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Export-Tag {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 11/21/2017
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Export vSphere Tags and VM Assocations to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.DESCRIPTION
|
||||
Export vSphere Tags and VM Assocations to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.EXAMPLE
|
||||
Export-Tag -Path C:\Users\primp\Desktop\VMworld2017
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$false)][String]$Path
|
||||
)
|
||||
|
||||
# Export Tag Categories
|
||||
$tagCatagorys = Get-TagCategory
|
||||
|
||||
$tagCatresults = @()
|
||||
foreach ($tagCategory in $tagCatagorys) {
|
||||
$tagCatObj = [pscustomobject] @{
|
||||
Name = $tagCategory.Name;
|
||||
Cardinality = $tagCategory.Cardinality;
|
||||
Description = $tagCategory.Description;
|
||||
Type = $tagCategory.EntityType
|
||||
}
|
||||
$tagCatresults+=$tagCatObj
|
||||
}
|
||||
if($Path) {
|
||||
$fullPath = $Path + "\AllTagCategory.json"
|
||||
Write-Host -ForegroundColor Green "Exporting vSphere Tag Category to $fullpath ..."
|
||||
$tagCatresults | ConvertTo-Json | Out-File $fullPath
|
||||
} else {
|
||||
$tagCatresults | ConvertTo-Json
|
||||
}
|
||||
|
||||
# Export Tags
|
||||
$tags = Get-Tag
|
||||
|
||||
$tagResults = @()
|
||||
foreach ($tag in $tags) {
|
||||
$tagObj = [pscustomobject] @{
|
||||
Name = $tag.Name;
|
||||
Description = $tag.Description;
|
||||
Category = $tag.Category.Name
|
||||
}
|
||||
$tagResults+=$tagObj
|
||||
}
|
||||
if($Path) {
|
||||
$fullPath = $Path + "\AllTag.json"
|
||||
Write-Host -ForegroundColor Green "Exporting vSphere Tag to $fullpath ..."
|
||||
$tagResults | ConvertTo-Json | Out-File $fullPath
|
||||
} else {
|
||||
$tagResults | ConvertTo-Json
|
||||
}
|
||||
|
||||
# Export VM to Tag Mappings
|
||||
$vms = Get-VM
|
||||
|
||||
$vmResults = @()
|
||||
foreach ($vm in $vms) {
|
||||
$tagAssignments = $vm | Get-TagAssignment
|
||||
$tags = @()
|
||||
foreach ($tagAssignment in $tagAssignments) {
|
||||
$tag = $tagAssignment.Tag
|
||||
$tagName = $tag -split "/"
|
||||
$tags+=$tagName
|
||||
}
|
||||
$vmObj = [pscustomobject] @{
|
||||
Name = $vm.name;
|
||||
Tag = $tags
|
||||
}
|
||||
$vmResults+=$vmObj
|
||||
}
|
||||
if($Path) {
|
||||
$fullPath = $Path + "\AllTagAssocations.json"
|
||||
Write-Host -ForegroundColor Green "Exporting VM to vSphere Tag Assignment to $fullpath ..."
|
||||
$vmResults | ConvertTo-Json | Out-File $fullPath
|
||||
} else {
|
||||
$vmResults | ConvertTo-Json
|
||||
}
|
||||
}
|
||||
|
||||
Function Import-Tag {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 11/21/2017
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Import vSphere Tags and VM Assocations from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.DESCRIPTION
|
||||
Import vSphere Tags and VM Assocations from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.EXAMPLE
|
||||
Import-Tag -Path C:\Users\primp\Desktop\VMworld2017
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$Path
|
||||
)
|
||||
|
||||
$tagCatFilename = "\AllTagCategory.json"
|
||||
$fullPath = $Path + $tagCatFilename
|
||||
$tagCategoryJson = Get-Content -Raw $fullPath | ConvertFrom-Json
|
||||
|
||||
$tagFilename = "\AllTag.json"
|
||||
$fullPath = $Path + $tagFilename
|
||||
$tagJson = Get-Content -Raw $fullPath | ConvertFrom-Json
|
||||
|
||||
$vmTagFilename = "\AllTagAssocations.json"
|
||||
$fullPath = $Path + $vmTagFilename
|
||||
$vmTagJson = Get-Content -Raw $fullPath | ConvertFrom-Json
|
||||
|
||||
# Re-Create Tag Category
|
||||
foreach ($category in $tagCategoryJson) {
|
||||
if($category.Cardinality -eq 0) {
|
||||
$cardinality = "Single"
|
||||
} else {
|
||||
$cardinality = "Multiple"
|
||||
}
|
||||
New-TagCategory -Name $category.Name -Cardinality $cardinality -Description $category.Description -EntityType $category.Type
|
||||
}
|
||||
|
||||
# Re-Create Tags
|
||||
foreach ($tag in $tagJson) {
|
||||
New-Tag -Name $tag.Name -Description $tag.Description -Category (Get-TagCategory -Name $tag.Category)
|
||||
}
|
||||
|
||||
# Re-Create VM to Tag Mappings
|
||||
foreach ($vmTag in $vmTagJson) {
|
||||
$vm = Get-VM -Name $vmTag.name
|
||||
$tags = $vmTag.Tag
|
||||
foreach ($tag in $tags) {
|
||||
New-TagAssignment -Entity $vm -Tag (Get-Tag -Name $tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Export-VMFolder {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 11/21/2017
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Export vSphere Folder to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.DESCRIPTION
|
||||
Export vSphere Folder to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.EXAMPLE
|
||||
Export-VMFolder -Path C:\Users\primp\Desktop\VMworld2017
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$false)][String]$Path
|
||||
)
|
||||
$vms = Get-VM
|
||||
|
||||
$vmFolderResults = @()
|
||||
foreach ($vm in $vms) {
|
||||
$vmFolderObj = [pscustomobject] @{
|
||||
Name = $vm.name;
|
||||
Folder = $vm.Folder.Name;
|
||||
}
|
||||
$vmFolderResults+=$vmFolderObj
|
||||
}
|
||||
if($Path) {
|
||||
$fullPath = $Path + "\AllVMFolder.json"
|
||||
Write-Host -ForegroundColor Green "Exporting VM Folders to $fullpath ..."
|
||||
$vmFolderResults | ConvertTo-Json | Out-File $fullPath
|
||||
} else {
|
||||
$vmFolderResults | ConvertTo-Json
|
||||
}
|
||||
}
|
||||
|
||||
Function Import-VMFolder {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 11/21/2017
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Import vSphere Folder from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.DESCRIPTION
|
||||
Import vSphere Folder from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
|
||||
.EXAMPLE
|
||||
Import-VMFolder -Path C:\Users\primp\Desktop\VMworld2017
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$Path
|
||||
)
|
||||
|
||||
$vmFolderFilename = "\AllVMFolder.json"
|
||||
$fullPath = $Path + $vmFolderFilename
|
||||
$vmFolderJson = Get-Content -Raw $fullPath | ConvertFrom-Json
|
||||
|
||||
# Root vm Folder
|
||||
$rootVMFolder = Get-Folder -Type VM -Name vm
|
||||
|
||||
$folders = $vmFolderJson | Select Folder | Sort-Object -Property Folder -Unique
|
||||
foreach ($folder in $folders) {
|
||||
$rootVMFolder | New-Folder -Name $folder.folder
|
||||
}
|
||||
|
||||
foreach ($vmFolder in $vmFolderJson) {
|
||||
$vm = Get-VM -Name $vmFolder.Name
|
||||
$folder = Get-Folder -Name $vmFolder.Folder
|
||||
Move-VM -VM $vm -Destination $folder
|
||||
}
|
||||
}
|
||||
|
||||
Function Export-VMStoragePolicy {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 11/21/2017
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Export VM Storage Policies to JSON file
|
||||
.DESCRIPTION
|
||||
Export VM Storage Policies to JSON file
|
||||
.EXAMPLE
|
||||
Export-VMStoragePolicy -Path C:\Users\primp\Desktop\VMworld2017
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$false)][String]$Path
|
||||
)
|
||||
|
||||
foreach ($policy in Get-SpbmStoragePolicy) {
|
||||
$policyName = $policy.Name
|
||||
if($Path) {
|
||||
Write-Host -ForegroundColor Green "Exporting Policy $policyName to $Path\$policyName.xml ..."
|
||||
$policy | Export-SpbmStoragePolicy -FilePath $Path\$policyName.xml -Force | Out-Null
|
||||
} else {
|
||||
$policy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Import-VMStoragePolicy {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 11/21/2017
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Import VM Storage Policies from JSON file
|
||||
.DESCRIPTION
|
||||
Import VM Storage Policies from JSON file
|
||||
.EXAMPLE
|
||||
Import-VMStoragePolicy -Path C:\Users\primp\Desktop\VMworld2017
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$false)][String]$Path
|
||||
)
|
||||
|
||||
foreach ($file in Get-ChildItem -Path $Path -Filter *.xml) {
|
||||
$policyName = $file.name
|
||||
$policyName = $policyName.replace(".xml","")
|
||||
if(Get-SpbmStoragePolicy -Name $policyName -ErrorAction SilentlyContinue) {
|
||||
Continue
|
||||
} else {
|
||||
Write-Host "Importing Policy $policyname ..."
|
||||
Import-SpbmStoragePolicy -FilePath $Path\$file -Name $policyName
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Pester/00 Test Connect-CISServer Connection to VC.Tests.ps1
Normal file
37
Pester/00 Test Connect-CISServer Connection to VC.Tests.ps1
Normal file
@@ -0,0 +1,37 @@
|
||||
<#
|
||||
Script name: Test Connect-CISServer to VC.Tests.ps1
|
||||
Created on: 04/20/2017
|
||||
Author: Alan Renouf, @alanrenouf
|
||||
Description: The purpose of this pester test is to ensure the PowerCLI modules are imported and a connection can be made to a vCenter for the CIS Service
|
||||
Dependencies: Pester Module
|
||||
Example run:
|
||||
|
||||
Invoke-Pester -Script @{ Path = '.\Test Connect-CISServer to VC.Tests.ps1'; Parameters = @{ VCNAME="VC01.local"; VCUSER="Administrator@vsphere.local"; VCPASS="Admin!23"} }
|
||||
|
||||
#>
|
||||
|
||||
$VCUSER = $Parameters.Get_Item("VCUSER")
|
||||
$VCPASS = $Parameters.Get_Item("VCPASS")
|
||||
$VCNAME = $Parameters.Get_Item("VCNAME")
|
||||
|
||||
Describe "Checking PowerCLI Cmdlets available" {
|
||||
$cmdletname = "Connect-CISServer"
|
||||
It "Checking $cmdletname is available" {
|
||||
$command = Get-Command $cmdletname
|
||||
$command | Select Name, Version
|
||||
$command.Name| Should Be $cmdletname
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Connect-CISServer Tests" {
|
||||
|
||||
$connection = Connect-CISServer $VCName -User $VCUser -password $VCPass
|
||||
It "Connection is active" {
|
||||
$Global:DefaultCISServers[0].isconnected | Should Be $true
|
||||
}
|
||||
|
||||
It "Checking connected server name is $VCName" {
|
||||
$Global:DefaultCISServers[0] | Select *
|
||||
$Global:DefaultCISServers[0].name | Should Be $VCName
|
||||
}
|
||||
}
|
||||
36
Pester/00 Test Connect-VIServer Connection to VC.Tests.ps1
Normal file
36
Pester/00 Test Connect-VIServer Connection to VC.Tests.ps1
Normal file
@@ -0,0 +1,36 @@
|
||||
<#
|
||||
Script name: Test Connection to VC.ps1
|
||||
Created on: 07/15/2016
|
||||
Author: Alan Renouf, @alanrenouf
|
||||
Description: The purpose of this pester test is to ensure the PowerCLI modules are imported and a connection can be made to a vCenter
|
||||
Dependencies: Pester Module
|
||||
Example run:
|
||||
|
||||
Invoke-Pester -Script @{ Path = '.\Test Connection to VC.Tests.ps1'; Parameters = @{ VCNAME="VC01.local"; VCUSER="Administrator@vsphere.local"; VCPASS="Admin!23"} }
|
||||
|
||||
#>
|
||||
|
||||
$VCUSER = $Parameters.Get_Item("VCUSER")
|
||||
$VCPASS = $Parameters.Get_Item("VCPASS")
|
||||
$VCNAME = $Parameters.Get_Item("VCNAME")
|
||||
|
||||
Describe "Checking PowerCLI Cmdlets available" {
|
||||
$cmdletname = "Connect-VIServer"
|
||||
It "Checking $cmdletname is available" {
|
||||
$command = Get-Command $cmdletname
|
||||
$command | Select Name, Version
|
||||
$command.Name| Should Be $cmdletname
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Connect-VIServer Tests" {
|
||||
|
||||
$connection = Connect-VIServer $VCName -User $VCUser -password $VCPass
|
||||
It "Connection is active" {
|
||||
$Global:DefaultVIServer[0].isconnected | Should Be $true
|
||||
}
|
||||
|
||||
It "Checking connected server name is $VCName" {
|
||||
$Global:DefaultVIServer[0].name | Should Be $VCName
|
||||
}
|
||||
}
|
||||
92
Pester/Get-DatastoreProvisioned.Tests.ps1
Normal file
92
Pester/Get-DatastoreProvisioned.Tests.ps1
Normal file
@@ -0,0 +1,92 @@
|
||||
# To run: "Invoke-Pester <path>\Get-DatastoreProvisioned.Tests.ps1"
|
||||
|
||||
<#
|
||||
Script name: Get-DatastoreProvisioned.Tests.ps1
|
||||
Created on: 2016/07/27
|
||||
Author: Brian Bunke, @brianbunke
|
||||
Description: Help validate that any changes to Get-DatastoreProvisioned.ps1 do not break existing functionality
|
||||
Dependencies: Pester
|
||||
|
||||
===Tested Against Environment====
|
||||
vSphere Version: 6.0 U1/U2
|
||||
PowerCLI Version: PowerCLI 6.3 R1
|
||||
PowerShell Version: 5.0
|
||||
OS Version: Windows 7/10
|
||||
#>
|
||||
|
||||
# Tests file stored separately from actual script
|
||||
# Find where this file is running from, replace parent folder 'Pester' with 'Scripts'
|
||||
$Path = (Split-Path -Parent $MyInvocation.MyCommand.Path).Replace("Pester","Scripts")
|
||||
# Remove the '.Tests.' from the file name
|
||||
$File = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
|
||||
# With changes made to the path, dot-source the function for testing
|
||||
. "$Path\$File"
|
||||
|
||||
Describe 'Get-DatastoreProvisioned' {
|
||||
# Need to create a few example objects to proxy Get-Datastore pipeline input
|
||||
$1 = [PSCustomObject]@{
|
||||
Name = 'iSCSI-spin'
|
||||
CapacityGB = 38.40
|
||||
FreeSpaceGB = 15.55
|
||||
ExtensionData = @{
|
||||
Summary = @{
|
||||
Capacity = 41234567890
|
||||
FreeSpace = 16696685366
|
||||
Uncommitted = 12345678999
|
||||
}}}
|
||||
$2 = [PSCustomObject]@{
|
||||
Name = 'iSCSI-ssd'
|
||||
CapacityGB = 51.74
|
||||
FreeSpaceGB = 10.35
|
||||
ExtensionData = @{
|
||||
Summary = @{
|
||||
Capacity = 55555555555
|
||||
FreeSpace = 11111111111
|
||||
Uncommitted = 23456765432
|
||||
}}}
|
||||
$3 = [PSCustomObject]@{
|
||||
Name = 'FC-ssd'
|
||||
CapacityGB = 10.35
|
||||
FreeSpaceGB = 4.14
|
||||
ExtensionData = @{
|
||||
Summary = @{
|
||||
Capacity = 11111111111
|
||||
FreeSpace = 4444444444
|
||||
Uncommitted = 2222222222
|
||||
}}}
|
||||
|
||||
It "Doesn't change existing functionality" {
|
||||
$StillWorks = $1,$2,$3 | Get-DatastoreProvisioned
|
||||
$StillWorks | Should Not BeNullOrEmpty
|
||||
($StillWorks | Measure-Object).Count | Should Be 3
|
||||
($StillWorks | Get-Member -MemberType NoteProperty).Count | Should Be 6
|
||||
'Name','FreeSpaceGB','CapacityGB','ProvisionedGB','UsedPct','ProvisionedPct' | ForEach-Object {
|
||||
($StillWorks | Get-Member -MemberType NoteProperty).Name -contains $_ | Should Be $true
|
||||
}
|
||||
}
|
||||
|
||||
It 'Still calculates correctly' {
|
||||
$calc = $1 | Get-DatastoreProvisioned
|
||||
$calc | Should Not BeNullOrEmpty
|
||||
$calc.ProvisionedGB | Should Be 34.35
|
||||
$calc.UsedPct | Should Be 59.51
|
||||
$calc.ProvisionedPct | Should Be 89.45
|
||||
}
|
||||
|
||||
# Get-Datastore | Get-DatastoreProvisioned | Format-Table -AutoSize
|
||||
It 'Follows Help Example 1' {
|
||||
$Help1 = $1,$2,$3 | Get-DatastoreProvisioned
|
||||
$Help1 | Should Not BeNullOrEmpty
|
||||
($Help1 | Measure-Object).Count | Should Be 3
|
||||
# not testing Format-Table
|
||||
}
|
||||
|
||||
# Get-Datastore -Name '*ssd' | Get-DatastoreProvisioned | Where-Object ProvisionedPct -ge 100
|
||||
It 'Follows Help Example 2' {
|
||||
$Help2 = $1,$2,$3 | Where Name -like '*ssd' | Get-DatastoreProvisioned | Where ProvisionedPct -ge 100
|
||||
$Help2 | Should Not BeNullOrEmpty
|
||||
($Help2 | Measure-Object).Count | Should Be 1
|
||||
$Help2.Name | Should BeExactly 'iSCSI-ssd'
|
||||
$Help2.ProvisionedPct | Should BeGreaterThan 100
|
||||
}
|
||||
}
|
||||
49
Pester/Test Get-CISService.Tests.ps1
Normal file
49
Pester/Test Get-CISService.Tests.ps1
Normal file
@@ -0,0 +1,49 @@
|
||||
<#
|
||||
Script name: Test Connect-CISService.Tests.ps1
|
||||
Created on: 04/20/2017
|
||||
Author: Alan Renouf, @alanrenouf
|
||||
Description: The purpose of this pester test is to ensure the CIS Service cmdlet works correctly
|
||||
Dependencies: Pester Module
|
||||
Example run:
|
||||
|
||||
Invoke-Pester -Script @{ Path = '.\Test Get-CISService.ps1' }
|
||||
|
||||
#>
|
||||
|
||||
Describe "Checking PowerCLI Cmdlets available" {
|
||||
$cmdletname = "Get-CISService"
|
||||
It "Checking $cmdletname is available" {
|
||||
$command = Get-Command $cmdletname
|
||||
$command | Select Name, Version
|
||||
$command.Name| Should Be $cmdletname
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Get-CISService Tests for services" {
|
||||
|
||||
It "Checking CIS connection is active" {
|
||||
$Global:DefaultCISServers[0].isconnected | Should Be $true
|
||||
}
|
||||
|
||||
It "Checking Get-CISService returns services" {
|
||||
Get-CISService | Should Be $true
|
||||
}
|
||||
|
||||
# Checking some known services which have a Get Method
|
||||
$servicestocheck = "com.vmware.appliance.system.version", "com.vmware.appliance.health.system"
|
||||
Foreach ($service in $servicestocheck) {
|
||||
It "Checking $service get method returns data" {
|
||||
Get-CisService -Name $service | Should Be $true
|
||||
(Get-CisService -Name $service).get() | Should Be $true
|
||||
}
|
||||
}
|
||||
|
||||
# Checking some known services which have a List Method
|
||||
$servicestocheck = "com.vmware.vcenter.folder", "com.vmware.vcenter.vm"
|
||||
Foreach ($service in $servicestocheck) {
|
||||
It "Checking $service list method returns data" {
|
||||
Get-CisService -Name $service | Should Be $true
|
||||
(Get-CisService -Name $service).list() | Should Be $true
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Pester/ZZ Test Disconnect-CISServer to VC.Tests.ps1
Normal file
20
Pester/ZZ Test Disconnect-CISServer to VC.Tests.ps1
Normal file
@@ -0,0 +1,20 @@
|
||||
<#
|
||||
Script name: Test Disconnect-CISServer to VC.Tests.ps1
|
||||
Created on: 04/20/2017
|
||||
Author: Alan Renouf, @alanrenouf
|
||||
Description: The purpose of this pester test is to ensure the Disconnect-CISServer cmdlet disconnects
|
||||
Dependencies: Pester Module
|
||||
Example run:
|
||||
|
||||
Invoke-Pester -Script @{ Path = '.\Test Disconnect-CISServer to VC.Tests.ps1'; Parameters = @{ VCNAME="VC01.local" } }
|
||||
|
||||
#>
|
||||
|
||||
$VCNAME = $Parameters.Get_Item("VCNAME")
|
||||
|
||||
Describe "Disconnect-CISServer Tests" {
|
||||
It "Disconnect from $VCName" {
|
||||
Disconnect-CISServer $VCName -confirm:$false
|
||||
$Global:DefaultCISServers | Should Be $null
|
||||
}
|
||||
}
|
||||
20
Pester/ZZ Test Disconnect-VIServer to VC.Tests.ps1
Normal file
20
Pester/ZZ Test Disconnect-VIServer to VC.Tests.ps1
Normal file
@@ -0,0 +1,20 @@
|
||||
<#
|
||||
Script name: Test Disconnect-VIServer to VC.ps1
|
||||
Created on: 04/20/2017
|
||||
Author: Alan Renouf, @alanrenouf
|
||||
Description: The purpose of this pester test is to ensure the Disconnect-VIServer cmdlet disconnects
|
||||
Dependencies: Pester Module
|
||||
Example run:
|
||||
|
||||
Invoke-Pester -Script @{ Path = '.\Test Disconnect-VISServer to VC.ps1'; Parameters = @{ VCNAME="VC01.local" } }
|
||||
|
||||
#>
|
||||
|
||||
$VCNAME = $Parameters.Get_Item("VCNAME")
|
||||
|
||||
Describe "Disconnect-VIServer Tests" {
|
||||
It "Disconnect from $VCName" {
|
||||
Disconnect-VIServer $VCName -confirm:$false
|
||||
$Global:DefaultVIServer | Should Be $null
|
||||
}
|
||||
}
|
||||
51
PowerActions/VM-CdDrive-Report.ps1
Normal file
51
PowerActions/VM-CdDrive-Report.ps1
Normal file
@@ -0,0 +1,51 @@
|
||||
<#
|
||||
.MYNGC_REPORT
|
||||
KEY\(VM\)
|
||||
.LABEL
|
||||
VM CD-Drive Report
|
||||
.DESCRIPTION
|
||||
PowerActions Report Script that reports on VMs CD-Drive configuration, making it easy to find VMs holding onto ISOs that you
|
||||
need to update, or VMs that can't vMotion because they are tied into a physical resource from the ESXi host that is running it.
|
||||
VM object is key (as it's the first managed object in the output), enabling you the ability to right-click an entry in the
|
||||
report to edit the target VM. Script is able to report on VMs with multiple CD-Drives as well. Version 1.0, written by
|
||||
Aaron Smith (@awsmith99), published 07/29/2016.
|
||||
#>
|
||||
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.Cluster]
|
||||
$vParam
|
||||
);
|
||||
|
||||
[Array] $vmList = @( Get-VM -Location $vParam | Sort Name );
|
||||
|
||||
foreach ( $vmItem in $vmList )
|
||||
{
|
||||
[Array] $vmCdDriveList = @( Get-CDDrive -VM $vmItem );
|
||||
|
||||
foreach ( $vmCdDriveItem in $vmCdDriveList )
|
||||
{
|
||||
[String] $insertedElement = "";
|
||||
[String] $connectionType = "";
|
||||
|
||||
switch ( $vmCdDriveItem )
|
||||
{
|
||||
{ $_.IsoPath } { $insertedElement = $_.IsoPath; $connectionType = "ISO"; break; }
|
||||
{ $_.HostDevice } { $insertedElement = $_.HostDevice; $connectionType = "Host Device"; break; }
|
||||
{ $_.RemoteDevice } { $insertedElement = $_.RemoteDevice; $connectionType = "Remote Device"; break; }
|
||||
default { $insertedElement = "None"; $connectionType = "Client Device"; break; }
|
||||
}
|
||||
|
||||
$output = New-Object -TypeName PSObject;
|
||||
|
||||
$output | Add-Member -MemberType NoteProperty -Name "VM" -Value $vmItem
|
||||
$output | Add-Member -MemberType NoteProperty -Name "CD-Drive" -Value $vmCdDriveItem.Name;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "Connection" -Value $connectionType;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "Inserted" -Value $insertedElement;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "Connected" -Value $vmCdDriveItem.ConnectionState.Connected;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "StartConnected" -Value $vmCdDriveItem.ConnectionState.StartConnected;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "AllowGuestControl" -Value $vmCdDriveItem.ConnectionState.AllowGuestControl;
|
||||
$output;
|
||||
}
|
||||
}
|
||||
49
PowerActions/VM-Snapshot-Report.ps1
Normal file
49
PowerActions/VM-Snapshot-Report.ps1
Normal file
@@ -0,0 +1,49 @@
|
||||
<#
|
||||
.MYNGC_REPORT
|
||||
KEY\(VM\)
|
||||
.LABEL
|
||||
VM Snapshot Report
|
||||
.DESCRIPTION
|
||||
PowerActions Report Script that reports on VMs with snapshots along with their description, date of the snapshot, age in days of the snapshot, size of the snapshot in GB,
|
||||
the VM's provisioned vs. used space in GB, if the snapshot is the current one being used, its parent snapshot (if there is one), and the Power state of the VM itself. VM
|
||||
object is key (as it's the first managed object in the output), enabling you the ability to right-click an entry in the report to edit the target VM. Version 1.0, written
|
||||
by Aaron Smith (@awsmith99), published 08/10/2016.
|
||||
#>
|
||||
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.Cluster]
|
||||
$vParam
|
||||
);
|
||||
|
||||
[Array] $vmList = @( Get-VM -Location $vParam | Sort Name );
|
||||
|
||||
foreach ( $vmItem in $vmList )
|
||||
{
|
||||
[Array] $vmSnapshotList = @( Get-Snapshot -VM $vmItem );
|
||||
|
||||
foreach ( $snapshotItem in $vmSnapshotList )
|
||||
{
|
||||
$vmProvisionedSpaceGB = [Math]::Round( $vmItem.ProvisionedSpaceGB, 2 );
|
||||
$vmUsedSpaceGB = [Math]::Round( $vmItem.UsedSpaceGB, 2 );
|
||||
$snapshotSizeGB = [Math]::Round( $snapshotItem.SizeGB, 2 );
|
||||
$snapshotAgeDays = ((Get-Date) - $snapshotItem.Created).Days;
|
||||
|
||||
$output = New-Object -TypeName PSObject;
|
||||
|
||||
$output | Add-Member -MemberType NoteProperty -Name "VM" -Value $vmItem;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "Name" -Value $snapshotItem.Name;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "Description" -Value $snapshotItem.Description;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "Created" -Value $snapshotItem.Created;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "AgeDays" -Value $snapshotAgeDays;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "ParentSnapshot" -Value $snapshotItem.ParentSnapshot.Name;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "IsCurrentSnapshot" -Value $snapshotItem.IsCurrent;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "SnapshotSizeGB" -Value $snapshotSizeGB;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "ProvisionedSpaceGB" -Value $vmProvisionedSpaceGB;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "UsedSpaceGB" -Value $vmUsedSpaceGB;
|
||||
$output | Add-Member -MemberType NoteProperty -Name "PowerState" -Value $snapshotItem.PowerState;
|
||||
|
||||
$output;
|
||||
}
|
||||
}
|
||||
@@ -178,11 +178,10 @@ The VMware Technnology Preview License Agreement: <https://github.com/vmware/Pow
|
||||
|
||||
## Board Members
|
||||
|
||||
Board members are voulenteers from the PowerCLI community and VMware staff members, board members are not held responsible for any issues which may occur from running of scripts inside this repository.
|
||||
Board members are volunteers from the PowerCLI community and VMware staff members, board members are not held responsible for any issues which may occur from running of scripts inside this repository.
|
||||
|
||||
Members:
|
||||
* Josh Atwell (Community Member)
|
||||
* Mathieu Buisson (Community Member)
|
||||
* Luc Dekens (Community Member)
|
||||
* Jonathan Medd (Community Member)
|
||||
* Alan Renouf (VMware)
|
||||
@@ -190,4 +189,4 @@ Members:
|
||||
* Rynardt Spies (Community Member)
|
||||
|
||||
## Approval of Additions
|
||||
Items added to the repository, including items from the Board members, require 2 votes from the board members before being added to the repository. The approving members will have ideally downloaded and tested the item. When two “Approved for Merge” comments are added from board members, the pull can then be committed to the repository.
|
||||
Items added to the repository, including items from the Board members, require a review and approval from at least one board member before being added to the repository. The approving member/s will have verified for a lack of malicious code. Once an “Approved for Merge” comment has been added from a board member, the pull can then be committed to the repository.
|
||||
70
Scripts/AutomaticVMFSUnmap.ps1
Executable file
70
Scripts/AutomaticVMFSUnmap.ps1
Executable file
@@ -0,0 +1,70 @@
|
||||
<#
|
||||
.SYNOPSIS Retrieve the current VMFS Unmap priority for VMFS 6 datastore
|
||||
.NOTES Author: William Lam
|
||||
.NOTES Site: www.virtuallyghetto.com
|
||||
.NOTES Reference: http://www.virtuallyghetto.com/2016/10/configure-new-automatic-space-reclamation-vmfs-unmap-using-vsphere-6-5-apis.html
|
||||
.PARAMETER Datastore
|
||||
VMFS 6 Datastore to enable or disable VMFS Unamp
|
||||
.EXAMPLE
|
||||
Get-Datastore "mini-local-datastore-hdd" | Get-VMFSUnmap
|
||||
#>
|
||||
|
||||
Function Get-VMFSUnmap {
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl]$Datastore
|
||||
)
|
||||
|
||||
$datastoreInfo = $Datastore.ExtensionData.Info
|
||||
|
||||
if($datastoreInfo -is [VMware.Vim.VmfsDatastoreInfo] -and $datastoreInfo.Vmfs.MajorVersion -eq 6) {
|
||||
$datastoreInfo.Vmfs | select Name, UnmapPriority, UnmapGranularity
|
||||
} else {
|
||||
Write-Host "Not a VMFS Datastore and/or VMFS version is not 6.0"
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS Configure the VMFS Unmap priority for VMFS 6 datastore
|
||||
.NOTES Author: William Lam
|
||||
.NOTES Site: www.virtuallyghetto.com
|
||||
.NOTES Reference: http://www.virtuallyghetto.com/2016/10/configure-new-automatic-space-reclamation-vmfs-unmap-using-vsphere-6-5-apis.html
|
||||
.PARAMETER Datastore
|
||||
VMFS 6 Datastore to enable or disable VMFS Unamp
|
||||
.EXAMPLE
|
||||
Get-Datastore "mini-local-datastore-hdd" | Set-VMFSUnmap -Enabled $true
|
||||
.EXAMPLE
|
||||
Get-Datastore "mini-local-datastore-hdd" | Set-VMFSUnmap -Enabled $false
|
||||
#>
|
||||
|
||||
Function Set-VMFSUnmap {
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl]$Datastore,
|
||||
[String]$Enabled
|
||||
)
|
||||
|
||||
$vmhostView = ($Datastore | Get-VMHost).ExtensionData
|
||||
$storageSystem = Get-View $vmhostView.ConfigManager.StorageSystem
|
||||
|
||||
if($Enabled -eq $true) {
|
||||
$enableUNMAP = "low"
|
||||
$reconfigMessage = "Enabling Automatic VMFS Unmap for $Datastore"
|
||||
} else {
|
||||
$enableUNMAP = "none"
|
||||
$reconfigMessage = "Disabling Automatic VMFS Unmap for $Datastore"
|
||||
}
|
||||
|
||||
$uuid = $datastore.ExtensionData.Info.Vmfs.Uuid
|
||||
|
||||
Write-Host "$reconfigMessage ..."
|
||||
$storageSystem.UpdateVmfsUnmapPriority($uuid,$enableUNMAP)
|
||||
}
|
||||
19
Scripts/CreateVLANonStandardSwitch
Normal file
19
Scripts/CreateVLANonStandardSwitch
Normal file
@@ -0,0 +1,19 @@
|
||||
<#
|
||||
Script name: CreateVLANonStandardSwitch.ps1
|
||||
Created on: 10/26/2017
|
||||
Author: Alan Comstock, @Mr_Uptime
|
||||
Description: Adds VLANs to an existing standard switch
|
||||
Dependencies: None known
|
||||
PowerCLI Version: VMware PowerCLI 6.5 Release 1 build 4624819
|
||||
PowerShell Version: 5.1.14393.1532
|
||||
OS Version: Windows 10
|
||||
#>
|
||||
|
||||
$esxhost="HOSTNAME"
|
||||
$vswitch="vSwitch0"
|
||||
$vlanlist=10,20,30,40,50
|
||||
Foreach ($vlan in $vlanlist) {
|
||||
$portgroupname="VLAN " + $vlan
|
||||
Get-VMHost $esxhost | Get-VirtualSwitch -name $vswitch | New-VirtualPortGroup -Name $portgroupname -VLanId $vlan
|
||||
}
|
||||
#The End
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user