Compare commits
1044 Commits
kmruddy-pa
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
062749868d | ||
|
|
9055bf72f3 | ||
|
|
e02efdec9e | ||
|
|
346141e69e | ||
|
|
3c0a12f72a | ||
|
|
50ac249ec1 | ||
|
|
3634649afc | ||
|
|
9e4f03aebe | ||
|
|
0b3e4c9ea2 | ||
|
|
ce06c5372b | ||
|
|
20871aeffa | ||
|
|
524b0aac2f | ||
|
|
f748f2591e | ||
|
|
cd502a516b | ||
|
|
d43b7ec88b | ||
|
|
d70d246e34 | ||
|
|
d41905e00f | ||
|
|
2be8d05707 | ||
|
|
356b3c4d68 | ||
|
|
52d38656ed | ||
|
|
1480fdec06 | ||
|
|
ddc96d276e | ||
|
|
ee6e800726 | ||
|
|
101b92e28d | ||
|
|
fdebb39901 | ||
|
|
74f450fb75 | ||
|
|
25700a9ac2 | ||
|
|
414b6ccb62 | ||
|
|
3c6190a2be | ||
|
|
b68077e4c3 | ||
|
|
c67b7d47a9 | ||
|
|
9f468a5cc2 | ||
|
|
c6f51e944d | ||
|
|
e9f5fa2c52 | ||
|
|
366aef13c2 | ||
|
|
97799789da | ||
|
|
9b62032a26 | ||
|
|
c74ae8cd7d | ||
|
|
dbd5f7e907 | ||
|
|
91ab53cdf7 | ||
|
|
51d21ca815 | ||
|
|
e0e2d1bbdc | ||
|
|
80622414d6 | ||
|
|
b2e0decb68 | ||
|
|
d85c6096a3 | ||
|
|
6188524f90 | ||
|
|
d5f851339b | ||
|
|
829307318f | ||
|
|
9a302e0473 | ||
|
|
02fd75b6a1 | ||
|
|
3cd0fe0ca5 | ||
|
|
bc6d2e8a5f | ||
|
|
b9cdded704 | ||
|
|
d23db41cfb | ||
|
|
9b4ce6cf65 | ||
|
|
38a6dea1d9 | ||
|
|
77b9db2f4e | ||
|
|
9964e16338 | ||
|
|
7a43b1096b | ||
|
|
248a86f0a2 | ||
|
|
9546f492e1 | ||
|
|
de17729494 | ||
|
|
238adac0bd | ||
|
|
054910c219 | ||
|
|
d8857e63db | ||
|
|
680ef82866 | ||
|
|
c46d3522bd | ||
|
|
fcf5ab8828 | ||
|
|
5648fe1bec | ||
|
|
e83cfa1b0b | ||
|
|
4e9093d0e5 | ||
|
|
db96e946f3 | ||
|
|
6b82f226f7 | ||
|
|
b5915de07a | ||
|
|
99674644d8 | ||
|
|
8cfc5e4fa6 | ||
|
|
b1c98c0fa2 | ||
|
|
5b291a5ac0 | ||
|
|
0b5e119776 | ||
|
|
33e41a756e | ||
|
|
379ff32624 | ||
|
|
05d2016ff0 | ||
|
|
e293d7e365 | ||
|
|
1d96b6a340 | ||
|
|
7eb5651feb | ||
|
|
cc2c740738 | ||
|
|
13d0ef4b86 | ||
|
|
3b7653da71 | ||
|
|
3afa7eed5d | ||
|
|
96205f85b2 | ||
|
|
ded1ce575d | ||
|
|
95abde3a5a | ||
|
|
ba63d1643a | ||
|
|
38998cee05 | ||
|
|
ccdddba4e7 | ||
|
|
2ec8f92823 | ||
|
|
8830d3ec2d | ||
|
|
9d82c04d72 | ||
|
|
294071df19 | ||
|
|
a7cd4db523 | ||
|
|
5025ab9047 | ||
|
|
173c08216e | ||
|
|
1710f7ccbd | ||
|
|
dbb570e009 | ||
|
|
3c961963f1 | ||
|
|
a62b0006b8 | ||
|
|
5b9265d0ad | ||
|
|
2b62d20d13 | ||
|
|
0cbd85190c | ||
|
|
246a887e84 | ||
|
|
3077daaeb5 | ||
|
|
1dd718eb3a | ||
|
|
fb641c8a1c | ||
|
|
db68f439a3 | ||
|
|
32749fbd16 | ||
|
|
af57eab8b8 | ||
|
|
21f4e8734c | ||
|
|
8de76d1327 | ||
|
|
53ab16a241 | ||
|
|
0c6b0b0a95 | ||
|
|
7b8d982dd3 | ||
|
|
5d221fdb15 | ||
|
|
f0cf0f58bd | ||
|
|
04b0807ed5 | ||
|
|
09fad317e1 | ||
|
|
5a45f4ec85 | ||
|
|
5df4070717 | ||
|
|
9a02c0e1fa | ||
|
|
e872cc50d1 | ||
|
|
9519635847 | ||
|
|
83447772b6 | ||
|
|
9d9ebc504b | ||
|
|
88f15d9fe3 | ||
|
|
a8d656e879 | ||
|
|
0a94dd4658 | ||
|
|
8db1fe37a2 | ||
|
|
bffb3f7630 | ||
|
|
e308436f06 | ||
|
|
a9bc152266 | ||
|
|
ed4f05238f | ||
|
|
5fda0c70d5 | ||
|
|
bfccd7faeb | ||
|
|
6198fffb2d | ||
|
|
4f60f40a72 | ||
|
|
979463b66f | ||
|
|
0e8d0d9cf5 | ||
|
|
cbd9a9594c | ||
|
|
0f6839ba68 | ||
|
|
7dd8f4cabc | ||
|
|
63655338ee | ||
|
|
cf7277cf7c | ||
|
|
0dd8b6f046 | ||
|
|
9f78104a1f | ||
|
|
30b8fa5c6d | ||
|
|
dc51c284da | ||
|
|
d3848a097f | ||
|
|
38b3524beb | ||
|
|
fd9c63825c | ||
|
|
59f562d9ed | ||
|
|
7766772353 | ||
|
|
e52b7dab53 | ||
|
|
6ebbad11e9 | ||
|
|
8606722f6e | ||
|
|
13dc050dd2 | ||
|
|
80509a18a5 | ||
|
|
f07791e1dd | ||
|
|
19e507581f | ||
|
|
a31276bcdb | ||
|
|
16b3a0fe05 | ||
|
|
fa518f99ee | ||
|
|
1e8308d84c | ||
|
|
ef804e6a05 | ||
|
|
5426af92b7 | ||
|
|
ac6c923e90 | ||
|
|
ec2ffb87ae | ||
|
|
f5a4dbf4cd | ||
|
|
bda716b560 | ||
|
|
25f21ecfb5 | ||
|
|
3f43eed119 | ||
|
|
176590fb66 | ||
|
|
775498aa8a | ||
|
|
cb6076ac60 | ||
|
|
066dbb25f7 | ||
|
|
29c2cc0221 | ||
|
|
dcfd1c6caf | ||
|
|
b2498a3fc3 | ||
|
|
837d98960c | ||
|
|
c5d2cb9f09 | ||
|
|
c212b24cbb | ||
|
|
791f976665 | ||
|
|
023edb4959 | ||
|
|
c1e8ee9ab9 | ||
|
|
f4eb24821f | ||
|
|
dc5a755805 | ||
|
|
9abd96740a | ||
|
|
acc1ab14bf | ||
|
|
c1e3e1936e | ||
|
|
8aa673e375 | ||
|
|
927d5de17c | ||
|
|
67529beefa | ||
|
|
8621610ed8 | ||
|
|
2c1eafde18 | ||
|
|
7832d6e7ae | ||
|
|
d6565f9e26 | ||
|
|
ca508570fb | ||
|
|
b03c1a536d | ||
|
|
eb827499cd | ||
|
|
b2934bcbf1 | ||
|
|
68e777357c | ||
|
|
4ca1a612ab | ||
|
|
def74388ce | ||
|
|
69975a39ff | ||
|
|
63d52d4e60 | ||
|
|
6148e8ff89 | ||
|
|
14e81f78af | ||
|
|
5abdbe9702 | ||
|
|
88648e2db2 | ||
|
|
c53453abb2 | ||
|
|
b8030e4272 | ||
|
|
5fb63bb345 | ||
|
|
0cf0626f4c | ||
|
|
48df3710fd | ||
|
|
bac4cf704c | ||
|
|
8599b67b81 | ||
|
|
391660cdf4 | ||
|
|
64e0b52224 | ||
|
|
35859f68ba | ||
|
|
1a7acd4812 | ||
|
|
d5abcdfbbe | ||
|
|
f685181096 | ||
|
|
f6f10d1738 | ||
|
|
0c3cad8410 | ||
|
|
3c45bbc117 | ||
|
|
368ec747ac | ||
|
|
d64e0fbdc0 | ||
|
|
9532ea9fac | ||
|
|
b78fb11206 | ||
|
|
b0dcb843aa | ||
|
|
d2544c9418 | ||
|
|
8de5885437 | ||
|
|
7ecfd1309d | ||
|
|
91053171e7 | ||
|
|
dd4bb2f415 | ||
|
|
4d1436b857 | ||
|
|
4af6de8e1d | ||
|
|
3a91b48f15 | ||
|
|
91cac83589 | ||
|
|
222f75a6ca | ||
|
|
9a7dc6dd59 | ||
|
|
bd70bfb5dc | ||
|
|
5c3e80bbf6 | ||
|
|
f0e801fceb | ||
|
|
29b3b75604 | ||
|
|
efef60d86a | ||
|
|
0500e52750 | ||
|
|
cfd3ca222d | ||
|
|
ca6f6abeb7 | ||
|
|
f53c09ae03 | ||
|
|
0c3ff917d0 | ||
|
|
228de51f25 | ||
|
|
e24187a954 | ||
|
|
be7f982767 | ||
|
|
3a4dada48d | ||
|
|
a918eacdad | ||
|
|
76d01e7eb8 | ||
|
|
1191cf6f75 | ||
|
|
a4d766922a | ||
|
|
4b2113d44f | ||
|
|
d6b02fb0ad | ||
|
|
f4ef4b0e07 | ||
|
|
500e4022e7 | ||
|
|
20f387d2cf | ||
|
|
adba00b7e8 | ||
|
|
3d74470c70 | ||
|
|
23ad3e0f64 | ||
|
|
21182d762b | ||
|
|
747190c33d | ||
|
|
1e7033a66f | ||
|
|
c5c836d3d6 | ||
|
|
31fa1244fd | ||
|
|
46c3a91c9d | ||
|
|
3cf69178d5 | ||
|
|
f3c549a867 | ||
|
|
aa8d5e3c26 | ||
|
|
926260096f | ||
|
|
233c220dd6 | ||
|
|
e45aa0171d | ||
|
|
41f6194fdb | ||
|
|
98ae307c1f | ||
|
|
5d570cb0df | ||
|
|
a70e324282 | ||
|
|
1715d94892 | ||
|
|
e61587ac9b | ||
|
|
b940759bbf | ||
|
|
6da888fd19 | ||
|
|
118739b8fb | ||
|
|
33e038bbba | ||
|
|
1b0dd9f42e | ||
|
|
3f430900cf | ||
|
|
b1fa944909 | ||
|
|
22f0926161 | ||
|
|
9db267a14c | ||
|
|
1d251bde8a | ||
|
|
254e062e52 | ||
|
|
2182f6ba6f | ||
|
|
9c62ed266e | ||
|
|
39cc775d25 | ||
|
|
0d4ba8b4dc | ||
|
|
adfe78f236 | ||
|
|
fa9a3c5026 | ||
|
|
7a39d28314 | ||
|
|
ab266189c2 | ||
|
|
6797eb8156 | ||
|
|
5e66c56742 | ||
|
|
ddde669037 | ||
|
|
39499c240b | ||
|
|
a8a98e098e | ||
|
|
03272c1d2d | ||
|
|
5c210f3839 | ||
|
|
f11b9bd485 | ||
|
|
31e3accfe1 | ||
|
|
a7ff78fee0 | ||
|
|
1a3e397661 | ||
|
|
f83ceec0e8 | ||
|
|
c1e181ea11 | ||
|
|
dc74d06a9c | ||
|
|
478d913779 | ||
|
|
c7fcb1b186 | ||
|
|
ffe7d86921 | ||
|
|
764123f903 | ||
|
|
4d399cc5ef | ||
|
|
f50c067e80 | ||
|
|
49c0b44beb | ||
|
|
39a8539d97 | ||
|
|
ae16ef6e52 | ||
|
|
1b7ea80342 | ||
|
|
c506bf400a | ||
|
|
81763c04c2 | ||
|
|
e33fdc3453 | ||
|
|
8b40cf94ec | ||
|
|
03f685980f | ||
|
|
ef84482ee3 | ||
|
|
b7e1d95e83 | ||
|
|
35095fbea7 | ||
|
|
46db5d0f50 | ||
|
|
323b9e88f7 | ||
|
|
7bd49b7779 | ||
|
|
44fbae8d08 | ||
|
|
23a6bcf09b | ||
|
|
c49cf2f721 | ||
|
|
3653dd09bc | ||
|
|
fef2f32adf | ||
|
|
9de3195b32 | ||
|
|
0ba0b870af | ||
|
|
2c79a86531 | ||
|
|
5325596b2f | ||
|
|
f703e1c275 | ||
|
|
ff54be27cd | ||
|
|
db5cd60916 | ||
|
|
0cfbf635e7 | ||
|
|
cbf397df24 | ||
|
|
337dc077a9 | ||
|
|
5f6294cf67 | ||
|
|
10647481f1 | ||
|
|
4badbe5ff5 | ||
|
|
4436510b02 | ||
|
|
0887967dc3 | ||
|
|
9854561591 | ||
|
|
908f0ee95f | ||
|
|
823e150ef7 | ||
|
|
ee017eb822 | ||
|
|
723acfd811 | ||
|
|
a849a67527 | ||
|
|
64db788986 | ||
|
|
864a6446f0 | ||
|
|
e7222d13f7 | ||
|
|
b3e9ffc51d | ||
|
|
e9e8a14f19 | ||
|
|
b5563cc11a | ||
|
|
30fc960778 | ||
|
|
9c8a928cd7 | ||
|
|
c1cc32db4b | ||
|
|
5f3f41ff44 | ||
|
|
93e61262ff | ||
|
|
fde0627160 | ||
|
|
2a5eff4fd1 | ||
|
|
72864b7860 | ||
|
|
5f1a86e78b | ||
|
|
0576034d74 | ||
|
|
e8fdf541d4 | ||
|
|
f55ffc3b20 | ||
|
|
4c23a8a5d6 | ||
|
|
50559d9c6d | ||
|
|
6f22da7f67 | ||
|
|
c91a764ffe | ||
|
|
975a7baf8d | ||
|
|
f4fc007bd5 | ||
|
|
11181a95ec | ||
|
|
9e33329a96 | ||
|
|
4c9fab7b6c | ||
|
|
fd7429055d | ||
|
|
3134d1acd9 | ||
|
|
942db3940d | ||
|
|
a9d6acc44b | ||
|
|
19d6151380 | ||
|
|
2cebd97c01 | ||
|
|
25450e9003 | ||
|
|
f2b9ac0647 | ||
|
|
0cfb39779b | ||
|
|
423e752404 | ||
|
|
b95886558f | ||
|
|
3b5f501d72 | ||
|
|
db8f4407a0 | ||
|
|
31d785fc14 | ||
|
|
1760d4c963 | ||
|
|
d12619c64d | ||
|
|
528eca815c | ||
|
|
74dd5ef9fb | ||
|
|
45ac4a47fb | ||
|
|
fe603f60d6 | ||
|
|
1c54a37fbd | ||
|
|
d95806ea2f | ||
|
|
bda5a5a276 | ||
|
|
72a5555860 | ||
|
|
29fbb5bc59 | ||
|
|
360e190300 | ||
|
|
b8b48e40f8 | ||
|
|
ecc12a1884 | ||
|
|
bbc6d0f775 | ||
|
|
3e09f0a601 | ||
|
|
f926508d1f | ||
|
|
c01427f6f4 | ||
|
|
2bb82249ca | ||
|
|
b5111e1fab | ||
|
|
5c833d4ce5 | ||
|
|
b90c83ac56 | ||
|
|
f642290b2d | ||
|
|
a95e01066d | ||
|
|
6c578f7b78 | ||
|
|
3a61850b41 | ||
|
|
783319a624 | ||
|
|
f9ca007ae5 | ||
|
|
71915cde79 | ||
|
|
0e318d3e07 | ||
|
|
780e830205 | ||
|
|
2212477dff | ||
|
|
481845717c | ||
|
|
407be173e4 | ||
|
|
6cc6634628 | ||
|
|
9ff4c4f48c | ||
|
|
216ee7386f | ||
|
|
ff3d297e69 | ||
|
|
59ab2785e3 | ||
|
|
5efdf01810 | ||
|
|
24556bbe19 | ||
|
|
83899d2b7b | ||
|
|
e35e17a04d | ||
|
|
9073d8f3b2 | ||
|
|
a2fef29a71 | ||
|
|
d758b5ba4c | ||
|
|
0d75606d99 | ||
|
|
a2c896b81b | ||
|
|
16528c92b8 | ||
|
|
9845e9d16b | ||
|
|
5571a8900a | ||
|
|
25cfffa14f | ||
|
|
06d018c7a6 | ||
|
|
e6a4c09e6d | ||
|
|
81e60245d0 | ||
|
|
4652495ece | ||
|
|
8953a512fe | ||
|
|
bfbcbc8faa | ||
|
|
bf33a58232 | ||
|
|
44879d8c25 | ||
|
|
334f58476c | ||
|
|
3372f3faf3 | ||
|
|
c906e8a772 | ||
|
|
faa125fd83 | ||
|
|
0246451fe6 | ||
|
|
9f851b38a1 | ||
|
|
dcc04b8d88 | ||
|
|
5dc0145c92 | ||
|
|
726eb7e181 | ||
|
|
c384c84892 | ||
|
|
70edda9043 | ||
|
|
82c7889cec | ||
|
|
76eadeba8a | ||
|
|
ac650e4a36 | ||
|
|
bd983dcd7f | ||
|
|
cea57f11d5 | ||
|
|
c7a19c795e | ||
|
|
e5920d40f5 | ||
|
|
4ef4cce5ef | ||
|
|
53b8377c53 | ||
|
|
f9953ec994 | ||
|
|
937f213451 | ||
|
|
7c7f8d3fbf | ||
|
|
971e4aeec7 | ||
|
|
0caddf91fa | ||
|
|
560739222d | ||
|
|
3e28c516a7 | ||
|
|
1ce8b927ce | ||
|
|
82b32df293 | ||
|
|
0743c67799 | ||
|
|
cb9e57e185 | ||
|
|
374baa8c7f | ||
|
|
ce32e7ab1d | ||
|
|
bcff03c896 | ||
|
|
37c9effbd7 | ||
|
|
a7b81266bd | ||
|
|
b5d8306bd4 | ||
|
|
56cab055f6 | ||
|
|
934fcc45af | ||
|
|
578d3c5deb | ||
|
|
3904b416b3 | ||
|
|
b68dc6c4e0 | ||
|
|
48d2db91d8 | ||
|
|
501bfa7fd2 | ||
|
|
4246cfc71f | ||
|
|
0581d89cbe | ||
|
|
b25c280714 | ||
|
|
82b5b2eb1e | ||
|
|
ea4ab5f61d | ||
|
|
ed5b8eaf5e | ||
|
|
2bb2cd451f | ||
|
|
3a1afa39fa | ||
|
|
8402e69993 | ||
|
|
a1c3c01f05 | ||
|
|
5052044ae1 | ||
|
|
3a022777d3 | ||
|
|
179cfa82be | ||
|
|
39c179ae1a | ||
|
|
691709dd40 | ||
|
|
16b32f1b03 | ||
|
|
526f6a8ad9 | ||
|
|
e8b64517c7 | ||
|
|
9e569b139a | ||
|
|
5ee5c5d09a | ||
|
|
21fe9a8d55 | ||
|
|
9c427a4886 | ||
|
|
14ecf2107d | ||
|
|
10f1f26ec1 | ||
|
|
9a4acf5c57 | ||
|
|
2103438f8a | ||
|
|
c49f893044 | ||
|
|
4c88b337aa | ||
|
|
e51b3050e2 | ||
|
|
b32256de5f | ||
|
|
c34b602bf3 | ||
|
|
5b74c582b7 | ||
|
|
33bb7f6b3a | ||
|
|
75a2562d97 | ||
|
|
a753d8251b | ||
|
|
760c534cf7 | ||
|
|
127252196f | ||
|
|
7086f2c823 | ||
|
|
dc191995f3 | ||
|
|
cca008ed27 | ||
|
|
1f6ec2c2c2 | ||
|
|
3c5e8363ed | ||
|
|
cff2f29b97 | ||
|
|
3d29306cb6 | ||
|
|
121c1bd2db | ||
|
|
a332102392 | ||
|
|
3366bb25e0 | ||
|
|
7b22e46772 | ||
|
|
a36bdf923d | ||
|
|
8ae75925af | ||
|
|
61a9929bca | ||
|
|
50b76efef6 | ||
|
|
a24fbf4e95 | ||
|
|
fc270dc256 | ||
|
|
348eb1899e | ||
|
|
b096ace8ae | ||
|
|
fe6932a5fe | ||
|
|
ad76a77c20 | ||
|
|
3eb90cf148 | ||
|
|
c2261080ff | ||
|
|
355d499301 | ||
|
|
d9768c21ac | ||
|
|
2200c4d25d | ||
|
|
f567922869 | ||
|
|
e345493124 | ||
|
|
e36208e2db | ||
|
|
189dbd13b5 | ||
|
|
b88f3a286a | ||
|
|
a8b54df5ff | ||
|
|
0a1e5a65c3 | ||
|
|
dd5f70caca | ||
|
|
2c23ecb414 | ||
|
|
eff217ab5d | ||
|
|
b90c1ecad0 | ||
|
|
3dda8cc639 | ||
|
|
c09c40b8b2 | ||
|
|
de8d765719 | ||
|
|
de1197d0e6 | ||
|
|
40026511e9 | ||
|
|
8c0e1985b1 | ||
|
|
8dbea3ac24 | ||
|
|
73d7eaa992 | ||
|
|
642e83e6fd | ||
|
|
aaae686d7c | ||
|
|
69397e76ce | ||
|
|
3121a12808 | ||
|
|
e2ad078168 | ||
|
|
c6607eb188 | ||
|
|
e5c0d95cb0 | ||
|
|
fb5c9e248a | ||
|
|
7c28fbc894 | ||
|
|
60217aaa5c | ||
|
|
748adc6f27 | ||
|
|
83b4f78c72 | ||
|
|
e83d70081c | ||
|
|
8694c40210 | ||
|
|
f4ba11fe75 | ||
|
|
056df11512 | ||
|
|
9d929431b0 | ||
|
|
f584dae11e | ||
|
|
5852e5bf7f | ||
|
|
948a5539a9 | ||
|
|
fc02a60eaf | ||
|
|
95138e128f | ||
|
|
60aafba7ae | ||
|
|
3b44fbcf20 | ||
|
|
9bd66f1a66 | ||
|
|
049e621fb6 | ||
|
|
29719d6ca7 | ||
|
|
13649b8e35 | ||
|
|
df9d71d4e0 | ||
|
|
d70bee9f99 | ||
|
|
d4f4e64ca3 | ||
|
|
c4c92f7a87 | ||
|
|
d987a7535b | ||
|
|
373b909095 | ||
|
|
054d127f12 | ||
|
|
7235de655d | ||
|
|
245cacae25 | ||
|
|
cdff3035cc | ||
|
|
c265c50447 | ||
|
|
969d31fcfb | ||
|
|
5a0bb408ba | ||
|
|
fa6be16f34 | ||
|
|
bad590dbc2 | ||
|
|
a68325cc50 | ||
|
|
009a298bff | ||
|
|
58c110be5a | ||
|
|
b2d62e84ad | ||
|
|
f8d285e9b5 | ||
|
|
03041fea20 | ||
|
|
e240f04de9 | ||
|
|
aaed5597d6 | ||
|
|
08cbf5276c | ||
|
|
9282c79c86 | ||
|
|
74dcf88b05 | ||
|
|
e53df3dc57 | ||
|
|
cda9bd36e1 | ||
|
|
a6f8d7db15 | ||
|
|
1fef21bad6 | ||
|
|
f7da4a963f | ||
|
|
f0f5ec7967 | ||
|
|
0109a2d0d2 | ||
|
|
5dfaf81e73 | ||
|
|
e73ababdcc | ||
|
|
f1669f8794 | ||
|
|
3e50b4ebde | ||
|
|
9c2b190faa | ||
|
|
a4a976e835 | ||
|
|
e887ac3152 | ||
|
|
8a4abe7dd4 | ||
|
|
a9c83ab50a | ||
|
|
e0e4a56826 | ||
|
|
cd2e8503ba | ||
|
|
61aead2685 | ||
|
|
4c645a7393 | ||
|
|
ecdd19911f | ||
|
|
5e844cf2cf | ||
|
|
b21e3d4fc0 | ||
|
|
5bee9abf62 | ||
|
|
02286dbe53 | ||
|
|
23f215be35 | ||
|
|
7217cec777 | ||
|
|
b5800f0eff | ||
|
|
dd9a0a16fa | ||
|
|
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 | ||
|
|
b39e6394db | ||
|
|
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 | ||
|
|
99673b1dfa | ||
|
|
3403db0ead | ||
|
|
2f595f086d | ||
|
|
e7c968d32b | ||
|
|
8469b3a285 | ||
|
|
456bd28b45 | ||
|
|
41a79d34a7 | ||
|
|
32096f6e02 | ||
|
|
67ba5de622 | ||
|
|
c8b2607b94 | ||
|
|
fd3c02b434 | ||
|
|
eae378822b | ||
|
|
e6744ea742 | ||
|
|
4464bf001b | ||
|
|
2a9a1b576b | ||
|
|
06d3eed37d | ||
|
|
6c49ae183f | ||
|
|
9187c45589 | ||
|
|
c342a7c3d4 | ||
|
|
677a5ce734 | ||
|
|
44abee7538 | ||
|
|
3ed0aa9ca4 | ||
|
|
ae5456560d | ||
|
|
beaeddba59 | ||
|
|
d20e5735e7 | ||
|
|
2f40185ceb | ||
|
|
b7d31ca3f4 | ||
|
|
deadb6f2c3 |
0
.gitattributes
vendored
Normal file
0
.gitattributes
vendored
Normal file
53
.gitignore
vendored
Normal file
53
.gitignore
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
# PowerShell Studio Files
|
||||
*.temppoint.*
|
||||
*.psproj.psbuild
|
||||
*.psbuild
|
||||
|
||||
#VS Code Files
|
||||
*.vscode
|
||||
/.vs
|
||||
|
||||
# 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
|
||||
/Modules/VMware.vSphere.SsoAdmin/ForPSGallery/VMware.vSphere.SsoAdmin
|
||||
12
LICENSE.txt
Normal file
12
LICENSE.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
PowerCLI-Example-Scripts
|
||||
Copyright 2021 VMware, Inc.
|
||||
|
||||
BSD 2-Clause License
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
554
Modules/Backup-VCSA/Backup-VCSA.psm1
Normal file
554
Modules/Backup-VCSA/Backup-VCSA.psm1
Normal file
@@ -0,0 +1,554 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
Function Backup-VCSAToFile {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Graf
|
||||
Date: October 30, 2016
|
||||
Organization: VMware
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
===========================================================================
|
||||
|
||||
.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
|
||||
A CisService can also be supplied as a parameter.
|
||||
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', 'SMB', 'SFTP')]
|
||||
$LocationType = "FTP",
|
||||
$Location,
|
||||
$LocationUser,
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$LocationPassword,
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$BackupPassword,
|
||||
$Comment = "Backup job",
|
||||
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers,
|
||||
[switch]$ShowProgress
|
||||
)
|
||||
Begin {
|
||||
if ($CisServer.IsConnected) {
|
||||
Write-Verbose "Connected to $($CisServer.Name)"
|
||||
$connection = $CisServer
|
||||
} elseif ($CisServer.gettype().name -eq "String") {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
|
||||
$Connection = Connect-CisServer $CisServer
|
||||
} elseif ($global:DefaultCisServers) {
|
||||
$connection = $global:DefaultCisServers
|
||||
} elseif ($global:DefaultVIServer) {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
}
|
||||
if (!$Connection) {
|
||||
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
|
||||
}
|
||||
if ($FullBackup) {$parts = @("common","seat")}
|
||||
if ($CommonBackup) {$parts = @("common")}
|
||||
|
||||
# Per github issue 468 (https://github.com/vmware/PowerCLI-Example-Scripts/issues/468) adding some logic to account for SFTP/SCP handling in versions after VC 7.0.
|
||||
$vCenterVersionNumber = (Get-CisService -Name 'com.vmware.appliance.system.version').get().version
|
||||
if ( ($vCenterVersionNumber -ge 6.5 -AND $vCenterVersionNumber -lt 7.0 ) -AND $LocationType -eq 'SFTP' ) {
|
||||
write-warning 'VCSA Backup for versions 6.5 and 6.7 use SCP, not SFTP. Adjusting the LocationType accordingly.'
|
||||
$LocationType = 'SCP'
|
||||
}
|
||||
if ( $vCenterVersionNumber -ge 7.0 -AND $LocationType -eq 'SCP' ) {
|
||||
write-warning 'VCSA Backup starting with version 7.0 use SFTP and not SCP. Adjusting the LocationType accordingly.'
|
||||
$LocationType = 'SFTP'
|
||||
}
|
||||
}
|
||||
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-Object 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-Object id, progress, state
|
||||
} Else {
|
||||
$BackupJob | Select-Object id, progress, state
|
||||
}
|
||||
}
|
||||
End {}
|
||||
}
|
||||
|
||||
Function Get-VCSABackupJobs {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Graf
|
||||
Date: October 30, 2016
|
||||
Organization: VMware
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
===========================================================================
|
||||
|
||||
.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
|
||||
.EXAMPLE
|
||||
PS C:\> Get-VCSABackupJobs -ShowNewest -CisServer "vcserver.sphere.local"
|
||||
.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 (
|
||||
[Parameter(Mandatory=$false)][switch]$ShowNewest,
|
||||
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers
|
||||
)
|
||||
Begin {
|
||||
if ($CisServer.IsConnected) {
|
||||
Write-Verbose "Connected to $($CisServer.Name)"
|
||||
$connection = $CisServer
|
||||
} elseif ($CisServer.gettype().name -eq "String") {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
|
||||
$Connection = Connect-CisServer $CisServer
|
||||
} elseif ($global:DefaultCisServers) {
|
||||
$connection = $global:DefaultCisServers
|
||||
} elseif ($global:DefaultVIServer) {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
}
|
||||
if (!$Connection) {
|
||||
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
|
||||
}
|
||||
}
|
||||
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
|
||||
Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
===========================================================================
|
||||
|
||||
.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(Mandatory=$false,ValueFromPipeline=$True)][string[]]$BackupID,
|
||||
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers
|
||||
)
|
||||
Begin {
|
||||
if ($CisServer.IsConnected) {
|
||||
Write-Verbose "Connected to $($CisServer.Name)"
|
||||
$connection = $CisServer
|
||||
} elseif ($CisServer.gettype().name -eq "String") {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
|
||||
$Connection = Connect-CisServer $CisServer
|
||||
} elseif ($global:DefaultCisServers) {
|
||||
$connection = $global:DefaultCisServers
|
||||
} elseif ($global:DefaultVIServer) {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
}
|
||||
if (!$Connection) {
|
||||
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
|
||||
}
|
||||
}
|
||||
Process{
|
||||
$BackupAPI = Get-CisService 'com.vmware.appliance.recovery.backup.job'
|
||||
Foreach ($id in $BackupID) {
|
||||
$BackupAPI.get("$id") | Select-Object id, progress, state
|
||||
}
|
||||
}
|
||||
End {}
|
||||
}
|
||||
|
||||
Function New-VCSASchedule {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Original Created by: Brian Graf
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
Organization: VMware
|
||||
Created / Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
This function will allow you to create a scheduled to backup your
|
||||
VCSA appliance. (vSphere 6.7 and higher)
|
||||
.DESCRIPTION
|
||||
Use this function to create a schedule to backup your VCSA to a remote location
|
||||
.EXAMPLE
|
||||
The Below Create a schedule on Monday @11:30pm to FTP location 10.1.1.10:/vcsabackup/vcenter01
|
||||
and keep 4 backups with a Encryption Passowrd of "VMw@re123"
|
||||
|
||||
$location = "ftp://10.1.1.10/vcsabackup/vcenter01"
|
||||
$LocationUser = "admin"
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$locationPassword = "VMw@re123"
|
||||
$BHour = 23
|
||||
$BMin = 30
|
||||
$BDays = @("Monday")
|
||||
$MaxCount = 4
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$BackupPassword = "VMw@re123"
|
||||
|
||||
PS C:\> New-VCSASchedule -Location $location -LocationUser $LocationUser -LocationPassword $locationPassword -BackupHour $BHour -BackupMinute $BMin -backupDays $BDays -MaxCount $MaxCount -BackupPassword $BackupPassword
|
||||
.EXAMPLE
|
||||
The Below Create a schedule on Sunday & Wednesday @5:15am
|
||||
to NFS location 10.1.1.10:/vcsabackup/vcenter01
|
||||
keep 10 backups with a Encryption Passowrd of "VMw@re123"
|
||||
with Event Data included (Seat) and will delete any existing schedule.
|
||||
|
||||
$location = "nfs://10.1.1.10/vcsabackup/vcenter01"
|
||||
$LocationUser = "admin"
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$locationPassword = "VMw@re123"
|
||||
$BHour = 5
|
||||
$BMin = 15
|
||||
$BDays = @("Sunday", "Monday")
|
||||
$MaxCount = 10
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$BackupPassword = "VMw@re123"
|
||||
|
||||
PS C:\> New-VCSASchedule -IncludeSeat -force -Location $location -LocationUser $LocationUser -LocationPassword $locationPassword -BackupHour $BHour -BackupMinute $BMin -backupDays $BDays -MaxCount $MaxCount -BackupPassword $BackupPassword -CisServer "vcserver.sphere.local"
|
||||
.NOTES
|
||||
Credit goes to @AlanRenouf & @vBrianGraf for sharing the base of this function.
|
||||
You must be connected to the CisService for this to work, if you are not connected, the function will prompt you for your credentials
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]$Location,
|
||||
[Parameter(Mandatory=$true)]$LocationUser,
|
||||
[Parameter(Mandatory=$true)][VMware.VimAutomation.Cis.Core.Types.V1.Secret]$LocationPassword,
|
||||
[Parameter(Mandatory=$false)][VMware.VimAutomation.Cis.Core.Types.V1.Secret]$BackupPassword,
|
||||
[Parameter(Mandatory=$true)][ValidateRange(0,23)]$BackupHour,
|
||||
[Parameter(Mandatory=$true)][ValidateRange(0,59)]$BackupMinute,
|
||||
[Parameter(Mandatory=$true)][ValidateSet('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY', IgnoreCase = $False)][Array]$BackupDays = $null,
|
||||
[Parameter(Mandatory=$true)][Int]$MaxCount,
|
||||
[Parameter(Mandatory=$false)]$BackupID = "default",
|
||||
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers,
|
||||
[Parameter(Mandatory=$false)][switch]$IncludeSeat,
|
||||
[Parameter(Mandatory=$false)][switch]$Force
|
||||
)
|
||||
Begin {
|
||||
if ($CisServer.IsConnected) {
|
||||
Write-Verbose "Connected to $($CisServer.Name)"
|
||||
$connection = $CisServer
|
||||
} elseif ($CisServer.gettype().name -eq "String") {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
|
||||
$Connection = Connect-CisServer $CisServer
|
||||
} elseif ($global:DefaultCisServers) {
|
||||
$connection = $global:DefaultCisServers
|
||||
} elseif ($global:DefaultVIServer) {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
}
|
||||
if (!$Connection) {
|
||||
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
|
||||
}
|
||||
}
|
||||
Process{
|
||||
if (!(Test-VCSAScheduleSupport)) {
|
||||
Write-Error "This VCSA does not support Backup Schedules."
|
||||
return
|
||||
}
|
||||
$BackupAPI = Get-CisService -name 'com.vmware.appliance.recovery.backup.schedules'
|
||||
$CreateSpec = $BackupAPI.Help.create.spec.Create()
|
||||
$CreateSpec.backup_password = $BackupPassword
|
||||
$CreateSpec.location = $Location
|
||||
$CreateSpec.location_user = $LocationUser
|
||||
$CreateSpec.location_password = $LocationPassword
|
||||
$CreateSpec.Enable = $true
|
||||
$CreateSpec.recurrence_info.Hour = $BackupHour
|
||||
$CreateSpec.recurrence_info.Minute = $BackupMinute
|
||||
$CreateSpec.recurrence_info.Days = $BackupDays
|
||||
$CreateSpec.retention_info.max_count = $MaxCount
|
||||
if ($IncludeSeat) {
|
||||
$CreateSpec.parts = @("seat","common")
|
||||
} else {
|
||||
$CreateSpec.parts = @("common")
|
||||
}
|
||||
$CurrentSchedule = $BackupAPI.list()
|
||||
|
||||
|
||||
if ($CurrentSchedule.keys.value) {
|
||||
if($Force -or $PSCmdlet.ShouldContinue($CurrentSchedule.keys.value,'Delete Old Schedule')){
|
||||
$BackupAPI.delete($CurrentSchedule.keys.value)
|
||||
} else {
|
||||
Write-Error "There is an exisiting Schedule. Please delete before Creating a new one."
|
||||
return
|
||||
}
|
||||
}
|
||||
if ($PSCmdlet.ShouldProcess($BackupID, 'Create New Schedule.')) {
|
||||
try {
|
||||
$BackupJob = $BackupAPI.create($BackupID, $CreateSpec)
|
||||
}
|
||||
catch {
|
||||
throw $_.Exception.Message
|
||||
}
|
||||
}
|
||||
if ($BackupJob) {
|
||||
Write-Host "Backup up Job Created."
|
||||
return $BackupJob
|
||||
}
|
||||
}
|
||||
End {}
|
||||
}
|
||||
|
||||
Function Get-VCSASchedule {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Original Created by: Brian Graf
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
Organization: VMware
|
||||
Created / Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
This function will allow you to Get the scheduled backup of your
|
||||
VCSA appliance. (vSphere 6.7 and higher)
|
||||
.DESCRIPTION
|
||||
Use this function to Get the backup schedule for your VCSA appliance.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-VCSASchedule
|
||||
.EXAMPLE
|
||||
PS C:\> Get-VCSASchedule -ScheduleID 1 -CisServer "vcserver.sphere.local"
|
||||
.NOTES
|
||||
Credit goes to @AlanRenouf & @vBrianGraf for sharing the base of this function.
|
||||
Returns a simplified object with the schedule details.
|
||||
You must be connected to the CisService for this to work, if you are not connected, the function will prompt you for your credentials
|
||||
#>
|
||||
param (
|
||||
[Parameter(Mandatory=$False,HelpMessage="Will Filter List By ScheduleID")]$ScheduleID,
|
||||
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers
|
||||
)
|
||||
Begin {
|
||||
if ($CisServer.IsConnected) {
|
||||
Write-Verbose "Connected to $($CisServer.Name)"
|
||||
$connection = $CisServer
|
||||
} elseif ($CisServer.gettype().name -eq "String") {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
|
||||
$Connection = Connect-CisServer $CisServer
|
||||
} elseif ($global:DefaultCisServers) {
|
||||
$connection = $global:DefaultCisServers
|
||||
} elseif ($global:DefaultVIServer) {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
}
|
||||
if (!$Connection) {
|
||||
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
|
||||
}
|
||||
}
|
||||
Process{
|
||||
if (!(Test-VCSAScheduleSupport)) {
|
||||
Write-Error "This VCSA does not support Backup Schedules."
|
||||
return
|
||||
}
|
||||
$BackupAPI = Get-CisService -name 'com.vmware.appliance.recovery.backup.schedules'
|
||||
$Schedules = $BackupAPI.list()
|
||||
if ($Schedules.count -ge 1) {
|
||||
$ObjSchedule = @()
|
||||
foreach ($Schedule in $Schedules) {
|
||||
$ObjSchedule += $Schedule.values | Select-Object *,@{N = "ID"; e = {"$($schedule.keys.value)"}} -ExpandProperty recurrence_info -ExcludeProperty Help | Select-Object * -ExcludeProperty recurrence_info,Help | Select-Object * -ExpandProperty retention_info | Select-Object * -ExcludeProperty retention_info,Help
|
||||
}
|
||||
if ($ScheduleID) {
|
||||
$ObjSchedule = $ObjSchedule | Where-Object {$_.ID -eq $ScheduleID}
|
||||
}
|
||||
return $ObjSchedule
|
||||
} else {
|
||||
Write-Information "No Schedule Defined."
|
||||
}
|
||||
}
|
||||
End {}
|
||||
}
|
||||
|
||||
Function Remove-VCSASchedule {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Original Created by: Brian Graf
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
Organization: VMware
|
||||
Created / Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
============================================================================
|
||||
.SYNOPSIS
|
||||
This function will remove any scheduled backups of your
|
||||
VCSA appliance. (vSphere 6.7 and higher)
|
||||
.DESCRIPTION
|
||||
Use this function to remove the backup schedule for your VCSA appliance.
|
||||
.EXAMPLE
|
||||
PS C:\> Remove-VCSASchedule
|
||||
.EXAMPLE
|
||||
PS C:\> Remove-VCSASchedule -ScheduleID 1 -CisServer "vcserver.sphere.local"
|
||||
.NOTES
|
||||
Credit goes to @AlanRenouf & @vBrianGraf for sharing the base of this function.
|
||||
You must be connected to the CisService for this to work, if you are not connected, the function will prompt you for your credentials
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
|
||||
param (
|
||||
[Parameter(Mandatory=$false)]$ScheduleID = "default",
|
||||
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers
|
||||
)
|
||||
Begin {
|
||||
if ($CisServer.IsConnected) {
|
||||
Write-Verbose "Connected to $($CisServer.Name)"
|
||||
$connection = $CisServer
|
||||
} elseif ($CisServer.gettype().name -eq "String") {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
|
||||
$Connection = Connect-CisServer $CisServer
|
||||
} elseif ($global:DefaultCisServers) {
|
||||
$connection = $global:DefaultCisServers
|
||||
} elseif ($global:DefaultVIServer) {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
}
|
||||
if (!$Connection) {
|
||||
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
|
||||
}
|
||||
}
|
||||
Process{
|
||||
if (!(Test-VCSAScheduleSupport)) {
|
||||
Write-Error "This VCSA does not support Backup Schedules."
|
||||
return
|
||||
}
|
||||
if ($PSCmdlet.ShouldProcess($ScheduleID, "Removes Current Backup Schedule")) {
|
||||
$BackupAPI = Get-CisService -name 'com.vmware.appliance.recovery.backup.schedules'
|
||||
$BackupAPI.delete($ScheduleID)
|
||||
}
|
||||
}
|
||||
End {}
|
||||
}
|
||||
|
||||
Function Test-VCSAScheduleSupport {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Original Created by: Brian Graf
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
Organization: VMware
|
||||
Created / Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function will check to see if your VCSA supports Scheduled Backups.
|
||||
(vSphere 6.7 and higher)
|
||||
.DESCRIPTION
|
||||
Use this function to check if your VCSA supports Scheduled Backups.
|
||||
.EXAMPLE
|
||||
PS C:\> Test-VCSAScheduleSupport
|
||||
.EXAMPLE
|
||||
PS C:\> Test-VCSAScheduleSupport -CisServer "vcserver.sphere.local"
|
||||
.NOTES
|
||||
Credit goes to @AlanRenouf & @vBrianGraf for sharing the base of this function.
|
||||
You must be connected to the CisService for this to work, if you are not connected, the function will prompt you for your credentia
|
||||
#>
|
||||
param (
|
||||
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers
|
||||
)
|
||||
Begin {
|
||||
if ($CisServer.IsConnected) {
|
||||
Write-Verbose "Connected to $($CisServer.Name)"
|
||||
$connection = $CisServer
|
||||
} elseif ($CisServer.gettype().name -eq "String") {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
|
||||
$Connection = Connect-CisServer $CisServer
|
||||
} elseif ($global:DefaultCisServers) {
|
||||
$connection = $global:DefaultCisServers
|
||||
} elseif ($global:DefaultVIServer) {
|
||||
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
}
|
||||
if (!$Connection) {
|
||||
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
|
||||
}
|
||||
}
|
||||
Process{
|
||||
if ((Get-CisService).name -contains "com.vmware.appliance.recovery.backup.schedules" ) {
|
||||
Write-Verbose "This VCSA does supports Backup Schedules."
|
||||
return $true
|
||||
} else {
|
||||
Write-Verbose "This VCSA does not support Backup Schedules."
|
||||
return $false
|
||||
}
|
||||
}
|
||||
End {}
|
||||
}
|
||||
784
Modules/ContentLibrary/ContentLibrary.psm1
Normal file
784
Modules/ContentLibrary/ContentLibrary.psm1
Normal file
@@ -0,0 +1,784 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
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
|
||||
)
|
||||
|
||||
$contentLibraryService = Get-CisService com.vmware.content.library
|
||||
$LibraryIDs = $contentLibraryService.list()
|
||||
|
||||
$results = @()
|
||||
foreach($libraryID in $LibraryIDs) {
|
||||
$library = $contentLibraryService.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
|
||||
)
|
||||
|
||||
$contentLibraryService = Get-CisService com.vmware.content.library
|
||||
$LibraryIDs = $contentLibraryService.list()
|
||||
|
||||
$results = @()
|
||||
foreach($libraryID in $LibraryIDs) {
|
||||
$library = $contentLibraryService.get($libraryId)
|
||||
if($library.name -eq $LibraryName) {
|
||||
$contentLibraryItemService = Get-CisService com.vmware.content.library.item
|
||||
$itemIds = $contentLibraryItemService.list($libraryID)
|
||||
|
||||
foreach($itemId in $itemIds) {
|
||||
$item = $contentLibraryItemService.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
|
||||
)
|
||||
|
||||
$contentLibraryService = Get-CisService com.vmware.content.library
|
||||
$libraryIDs = $contentLibraryService.list()
|
||||
|
||||
$results = @()
|
||||
foreach($libraryID in $libraryIDs) {
|
||||
$library = $contentLibraryService.get($libraryId)
|
||||
if($library.name -eq $LibraryName) {
|
||||
$contentLibraryItemService = Get-CisService com.vmware.content.library.item
|
||||
$itemIds = $contentLibraryItemService.list($libraryID)
|
||||
$DatastoreID = $library.storage_backings.datastore_id.Value
|
||||
$Datastore = get-datastore -id "Datastore-$DatastoreID"
|
||||
|
||||
foreach($itemId in $itemIds) {
|
||||
$itemName = ($contentLibraryItemService.get($itemId)).name
|
||||
$contentLibraryItemFileSerice = Get-CisService com.vmware.content.library.item.file
|
||||
$files = $contentLibraryItemFileSerice.list($itemId)
|
||||
$contentLibraryItemStorageService = Get-CisService com.vmware.content.library.item.storage
|
||||
|
||||
foreach($file in $files) {
|
||||
if($contentLibraryItemStorageService.get($itemId, $($file.name)).storage_backing.type -eq "DATASTORE"){
|
||||
$filepath = $contentLibraryItemStorageService.get($itemId, $($file.name)).storage_uris.segments -notmatch '(^/$|^vmfs$*|^volumes$*|vsan:.*)' -join ''
|
||||
$fullfilepath = "[$($datastore.name)] $filepath"
|
||||
}
|
||||
else{
|
||||
$fullfilepath = "UNKNOWN"
|
||||
}
|
||||
|
||||
if(!$LibraryItemName) {
|
||||
$fileResult = [pscustomobject] @{
|
||||
Name = $file.name;
|
||||
Version = $file.version;
|
||||
Size = $file.size;
|
||||
Stored = $file.cached;
|
||||
Path = $fullfilepath;
|
||||
}
|
||||
$results+=$fileResult
|
||||
} else {
|
||||
if($itemName -eq $LibraryItemName) {
|
||||
$fileResult = [pscustomobject] @{
|
||||
Name = $file.name;
|
||||
Version = $file.version;
|
||||
Size = $file.size;
|
||||
Stored = $file.cached;
|
||||
Path = $fullfilepath;
|
||||
}
|
||||
$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
|
||||
)
|
||||
|
||||
$contentLibraryService = Get-CisService com.vmware.content.library
|
||||
$LibraryIDs = $contentLibraryService.list()
|
||||
|
||||
$found = $false
|
||||
foreach($libraryID in $LibraryIDs) {
|
||||
$library = $contentLibraryService.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 = $AutoSync
|
||||
$createSpec.subscription_info.on_demand = $OnDemand
|
||||
$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
|
||||
)
|
||||
|
||||
$contentLibraryService = Get-CisService com.vmware.content.library
|
||||
$LibraryIDs = $contentLibraryService.list()
|
||||
|
||||
$found = $false
|
||||
foreach($libraryID in $LibraryIDs) {
|
||||
$library = $contentLibraryService.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
|
||||
)
|
||||
|
||||
$contentLibraryService = Get-CisService com.vmware.content.library
|
||||
$LibraryIDs = $contentLibraryService.list()
|
||||
|
||||
$found = $false
|
||||
foreach($libraryID in $LibraryIDs) {
|
||||
$library = $contentLibraryService.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 SourceLibraryName
|
||||
The name of the source Content Library to copy from
|
||||
.PARAMETER DestinationLibraryName
|
||||
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 -SourceLibraryName Foo -DestinationLibraryName Bar
|
||||
.EXAMPLE
|
||||
Copy-ContentLibrary -SourceLibraryName Foo -DestinationLibraryName Bar -DeleteSourceFile $true
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$SourceLibraryName,
|
||||
[Parameter(Mandatory=$true)][String]$DestinationLibraryName,
|
||||
[Parameter(Mandatory=$false)][Boolean]$DeleteSourceFile=$false
|
||||
)
|
||||
|
||||
$sourceLibraryId = (Get-ContentLibrary -LibraryName $SourceLibraryName).Id
|
||||
if($sourceLibraryId -eq $null) {
|
||||
Write-Host -ForegroundColor red "Unable to find Source Content Library named $SourceLibraryName"
|
||||
exit
|
||||
}
|
||||
$destinationLibraryId = (Get-ContentLibrary -LibraryName $DestinationLibraryName).Id
|
||||
if($destinationLibraryId -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Unable to find Destination Content Library named $DestinationLibraryName"
|
||||
break
|
||||
}
|
||||
|
||||
$sourceItemFiles = Get-ContentLibraryItems -LibraryName $SourceLibraryName
|
||||
if($sourceItemFiles -eq $null) {
|
||||
Write-Host -ForegroundColor red "Unable to retrieve Content Library Items from $SourceLibraryName"
|
||||
break
|
||||
}
|
||||
|
||||
$contentLibraryItemService = 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 $DestinationLibraryName -LibraryItemName $sourceItemFile.Name
|
||||
|
||||
if($result -eq $null) {
|
||||
# Create CopySpec
|
||||
$copySpec = $contentLibraryItemService.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 = $contentLibraryItemService.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 = $contentLibraryItemService.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 = $contentLibraryItemService.delete($sourceItemFile.Id)
|
||||
} catch {
|
||||
Write-Host -ForegroundColor Red "Failed to delete" $sourceItemFile.Name
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function New-VMTX {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function clones a VM to VM Template in Content Library (currently only supported on VMC)
|
||||
.PARAMETER SourceVMName
|
||||
The name of the source VM to clone
|
||||
.PARAMETER VMTXName
|
||||
The name of the VM Template in Content Library
|
||||
.PARAMETER Description
|
||||
Description of the VM template
|
||||
.PARAMETER LibraryName
|
||||
The name of the Content Library to clone to
|
||||
.PARAMETER FolderName
|
||||
The name of vSphere Folder (Defaults to Workloads for VMC)
|
||||
.PARAMETER ResourcePoolName
|
||||
The name of the vSphere Resource Pool (Defaults to Compute-ResourcePools for VMC)
|
||||
.EXAMPLE
|
||||
New-VMTX -SourceVMName "Windows10-BaseInstall" -VMTXName "Windows10-VMTX-Template" -LibraryName "VMC-CL-01"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$SourceVMName,
|
||||
[Parameter(Mandatory=$true)][String]$VMTXName,
|
||||
[Parameter(Mandatory=$false)][String]$Description,
|
||||
[Parameter(Mandatory=$true)][String]$LibraryName,
|
||||
[Parameter(Mandatory=$false)][String]$FolderName="Workloads",
|
||||
[Parameter(Mandatory=$false)][String]$ResourcePoolName="Compute-ResourcePool"
|
||||
)
|
||||
|
||||
$vmtxService = Get-CisService -Name "com.vmware.vcenter.vm_template.library_items"
|
||||
|
||||
$sourceVMId = ((Get-VM -Name $SourceVMName).ExtensionData.MoRef).Value
|
||||
$libraryId = ((Get-ContentLibrary -LibraryName $LibraryName).Id).Value
|
||||
$folderId = ((Get-Folder -Name $FolderName).ExtensionData.MoRef).Value
|
||||
$rpId = ((Get-ResourcePool -Name $ResourcePoolName).ExtensionData.MoRef).Value
|
||||
|
||||
$vmtxCreateSpec = $vmtxService.Help.create.spec.Create()
|
||||
$vmtxCreateSpec.source_vm = $sourceVMId
|
||||
$vmtxCreateSpec.name = $VMTXName
|
||||
$vmtxCreateSpec.description = $Description
|
||||
$vmtxCreateSpec.library = $libraryId
|
||||
$vmtxCreateSpec.placement.folder = $folderId
|
||||
$vmtxCreateSpec.placement.resource_pool = $rpId
|
||||
|
||||
Write-Host "`nCreating new VMTX Template from $SourceVMName in Content Library $LibraryName ..."
|
||||
$result = $vmtxService.create($vmtxCreateSpec)
|
||||
}
|
||||
|
||||
Function New-VMFromVMTX {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function deploys a new VM from Template in Content Library (currently only supported in VMC)
|
||||
.PARAMETER VMTXName
|
||||
The name of the VM Template in Content Library to deploy from
|
||||
.PARAMETER NewVMName
|
||||
The name of the new VM to deploy
|
||||
.PARAMETER FolderName
|
||||
The name of vSphere Folder (Defaults to Workloads for VMC)
|
||||
.PARAMETER ResourcePoolName
|
||||
The name of the vSphere Resource Pool (Defaults to Compute-ResourcePools for VMC)
|
||||
.PARAMETER NumCpu
|
||||
The number of vCPU to configure for the new VM
|
||||
.PARAMETER MemoryMb
|
||||
The amount of memory (MB) to configure for the new VM
|
||||
.PARAMETER PowerOn
|
||||
To power on the VM after deploy
|
||||
.EXAMPLE
|
||||
New-VMFromVMTX -NewVMName "FooFoo" -VMTXName "FooBar" -PowerOn $true -NumCpu 4 -MemoryMB 2048
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$VMTXName,
|
||||
[Parameter(Mandatory=$true)][String]$NewVMName,
|
||||
[Parameter(Mandatory=$false)][String]$FolderName="Workloads",
|
||||
[Parameter(Mandatory=$false)][String]$ResourcePoolName="Compute-ResourcePool",
|
||||
[Parameter(Mandatory=$false)][String]$DatastoreName="WorkloadDatastore",
|
||||
[Parameter(Mandatory=$false)][Int]$NumCpu,
|
||||
[Parameter(Mandatory=$false)][Int]$MemoryMB,
|
||||
[Parameter(Mandatory=$false)][Boolean]$PowerOn=$false
|
||||
)
|
||||
|
||||
$vmtxService = Get-CisService -Name "com.vmware.vcenter.vm_template.library_items"
|
||||
$vmtxId = (Get-ContentLibraryItem -Name $VMTXName).Id
|
||||
$folderId = ((Get-Folder -Name $FolderName).ExtensionData.MoRef).Value
|
||||
$rpId = ((Get-ResourcePool -Name $ResourcePoolName).ExtensionData.MoRef).Value
|
||||
$datastoreId = ((Get-Datastore -Name $DatastoreName).ExtensionData.MoRef).Value
|
||||
|
||||
$vmtxDeploySpec = $vmtxService.Help.deploy.spec.Create()
|
||||
$vmtxDeploySpec.name = $NewVMName
|
||||
$vmtxDeploySpec.powered_on = $PowerOn
|
||||
$vmtxDeploySpec.placement.folder = $folderId
|
||||
$vmtxDeploySpec.placement.resource_pool = $rpId
|
||||
$vmtxDeploySpec.vm_home_storage.datastore = $datastoreId
|
||||
$vmtxDeploySpec.disk_storage.datastore = $datastoreId
|
||||
|
||||
if($NumCpu) {
|
||||
$vmtxDeploySpec.hardware_customization.cpu_update.num_cpus = $NumCpu
|
||||
}
|
||||
if($MemoryMB) {
|
||||
$vmtxDeploySpec.hardware_customization.memory_update.memory = $MemoryMB
|
||||
}
|
||||
|
||||
Write-Host "`nDeploying new VM $NewVMName from VMTX Template $VMTXName ..."
|
||||
$results = $vmtxService.deploy($vmtxId,$vmtxDeploySpec)
|
||||
}
|
||||
|
||||
Function New-SubscribedContentLibrary {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function creates a new Subscriber Content Library from Subscription URL
|
||||
.PARAMETER LibraryName
|
||||
The name of the new vSphere Content Library
|
||||
.PARAMETER DatastoreName
|
||||
The name of the vSphere Datastore to store the Content Library
|
||||
.PARAMETER SubscriptionURL
|
||||
The URL of the published Content Library
|
||||
.PARAMETER SubscriptionThumbprint
|
||||
The SSL Thumbprint for the published Content Library
|
||||
.PARAMETER OnDemand
|
||||
Specifies whether content is downloaded on-demand (e.g. no immediately)
|
||||
.PARAMETER AutomaticSync
|
||||
Specifies whether automatic synchronization with the external content library is enabled
|
||||
.EXAMPLE
|
||||
New-SubscribedContentLibrary -LibraryName NestedESXi -DatastoreName vsanDatastore -SubscriptionURL https://download3.vmware.com/software/vmw-tools/lib.json -SubscriptionThumbprint "7a:c4:08:2d:d3:55:56:af:9f:26:43:65:d0:31:99:0b:d2:f3:d8:69" -AutomaticSync
|
||||
.EXAMPLE
|
||||
New-SubscribedContentLibrary -LibraryName NestedESXi -DatastoreName vsanDatastore -SubscriptionURL https://download3.vmware.com/software/vmw-tools/lib.json -SubscriptionThumbprint "7a:c4:08:2d:d3:55:56:af:9f:26:43:65:d0:31:99:0b:d2:f3:d8:69" -OnDemand
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$LibraryName,
|
||||
[Parameter(Mandatory=$true)][String]$DatastoreName,
|
||||
[Parameter(Mandatory=$true)][String]$SubscriptionURL,
|
||||
[Parameter(Mandatory=$true)][String]$SubscriptionThumbprint,
|
||||
[Parameter(Mandatory=$false)][Switch]$OnDemand,
|
||||
[Parameter(Mandatory=$false)][Switch]$AutomaticSync
|
||||
)
|
||||
|
||||
$datastore = Get-Datastore -Name $DatastoreName
|
||||
|
||||
if($datastore) {
|
||||
$datastoreId = $datastore.ExtensionData.MoRef.Value
|
||||
$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
|
||||
$createSpec.type = "SUBSCRIBED"
|
||||
$addResults = $createSpec.storage_backings.Add($StorageSpec)
|
||||
|
||||
if($OnDemand) { $OnDemandFlag = $true } else { $OnDemandFlag = $false }
|
||||
if($AutomaticSync) { $AutomaticSyncFlag = $true } else { $AutomaticSyncFlag = $false }
|
||||
$createSpec.subscription_info.on_demand = $OnDemandFlag
|
||||
$createSpec.subscription_info.automatic_sync_enabled = $AutomaticSyncFlag
|
||||
$createSpec.subscription_info.subscription_url = $SubscriptionURL
|
||||
$createSpec.subscription_info.authentication_method = "NONE"
|
||||
$createSpec.subscription_info.ssl_thumbprint = $SubscriptionThumbprint
|
||||
|
||||
Write-Host "Creating new Subscribed Content Library called $LibraryName ..."
|
||||
$library = $subscribeLibraryService.create($UniqueChangeId, $createSpec)
|
||||
}
|
||||
}
|
||||
315
Modules/CrossvCentervmotion/XVM.psm1
Normal file
315
Modules/CrossvCentervmotion/XVM.psm1
Normal file
@@ -0,0 +1,315 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
Function Get-XVCMStatus {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function returns whether Cross vCenter Workload Migration Utility is running or not
|
||||
.EXAMPLE
|
||||
Get-XVCMStatus
|
||||
#>
|
||||
$Uri = "http://localhost:8080/api/status" #Updated for 2.0, Old: "http://localhost:8080/api/ping"
|
||||
|
||||
$results = Invoke-WebRequest -Uri $Uri -Method GET -TimeoutSec 5
|
||||
|
||||
if($results.StatusCode -eq 200) {
|
||||
Write-Host -ForegroundColor Green $results.Content
|
||||
} else { Write-Host -ForegroundColor Red "Cross vCenter Workload Migration Utility is probably not running" }
|
||||
}
|
||||
|
||||
Function Get-XVCMSite {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function returns all registered vCenter Servers
|
||||
.EXAMPLE
|
||||
Get-XVCMSite
|
||||
#>
|
||||
$Uri = "http://localhost:8080/api/sites"
|
||||
|
||||
$results = Invoke-WebRequest -Uri $Uri -Method GET
|
||||
|
||||
if($results.StatusCode -eq 200) {
|
||||
($results.Content | ConvertFrom-Json)|select sitename,hostname,username
|
||||
} else { Write-Host -ForegroundColor Red "Failed to retrieve VC Site Registration details" }
|
||||
}
|
||||
|
||||
Function New-XVCMSite {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function registers a new vCenter Server endpoint
|
||||
.PARAMETER SiteName
|
||||
The display name for the particular vCenter Server to be registered
|
||||
.PARAMETER VCHostname
|
||||
The Hostname/IP Address of vCenter Server
|
||||
.PARAMETER VCUsername
|
||||
The VC Username of vCenter Server
|
||||
.PARAMETER VCPassword
|
||||
The VC Password of vCenter Server
|
||||
.PARAMETER Insecure
|
||||
Flag to disable SSL Verification checking, useful for lab environments
|
||||
.EXAMPLE
|
||||
New-XVCMSite -SiteName "SiteA" -VCHostname "vcenter65-1.primp-industries.com" -VCUsername "administrator@vsphere.local" -VCPassword "VMware1!" -Insecure
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$SiteName,
|
||||
[Parameter(Mandatory=$true)][String]$VCHostname,
|
||||
[Parameter(Mandatory=$true)][String]$VCUsername,
|
||||
[Parameter(Mandatory=$true)][String]$VCPassword,
|
||||
[Parameter(Mandatory=$false)][Switch]$Insecure
|
||||
)
|
||||
|
||||
$Uri = "http://localhost:8080/api/sites"
|
||||
|
||||
$insecureFlag = $false
|
||||
if($Insecure) {
|
||||
$insecureFlag = $true
|
||||
}
|
||||
|
||||
$body = @{
|
||||
"sitename"=$SiteName;
|
||||
"hostname"=$VCHostname;
|
||||
"username"=$VCUsername;
|
||||
"password"=$VCPassword;
|
||||
"insecure"=$insecureFlag;
|
||||
}
|
||||
|
||||
$body = $body | ConvertTo-Json
|
||||
|
||||
Write-Host -ForegroundColor Cyan "Registering vCenter Server $VCHostname as $SiteName ..."
|
||||
$results = Invoke-WebRequest -Uri $Uri -Method POST -Body $body -ContentType "application/json"
|
||||
|
||||
if($results.StatusCode -eq 200) {
|
||||
Write-Host -ForegroundColor Green "Successfully registered $SiteName"
|
||||
} else { Write-Host -ForegroundColor Red "Failed to register $SiteName" }
|
||||
}
|
||||
|
||||
Function Remove-XVCMSite {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function removes vCenter Server endpoint
|
||||
.PARAMETER SiteName
|
||||
The name of the registered vCenter Server to remove
|
||||
.EXAMPLE
|
||||
Remove-XVCMSite -SiteName "SiteA"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$SiteName
|
||||
)
|
||||
|
||||
$Uri = "http://localhost:8080/api/sites/$SiteName"
|
||||
|
||||
Write-Host -ForegroundColor Cyan "Deleting vCenter Server Site Registerion $SiteName ..."
|
||||
$results = Invoke-WebRequest -Uri $Uri -Method DELETE
|
||||
|
||||
if($results.StatusCode -eq 200) {
|
||||
Write-Host -ForegroundColor Green "Successfully deleted $SiteName"
|
||||
} else { Write-Host -ForegroundColor Red "Failed to deleted $SiteName" }
|
||||
}
|
||||
|
||||
Function New-XVCMRequest {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function initiates a migration request
|
||||
.PARAMETER opType
|
||||
The type of task, Relocate or Clone
|
||||
.PARAMETER SrcSite
|
||||
The name of the source vCenter Server
|
||||
.PARAMETER DstSite
|
||||
The name of the destination vCenter Server
|
||||
.PARAMETER SrcDatacenter
|
||||
The name of the source vSphere Datacenter
|
||||
.PARAMETER DstDatacenter
|
||||
The name of the destination vSphere Datacenter
|
||||
.PARAMETER DstCluster
|
||||
The name of the destination vSphere Cluster, set to null if DstHost is defined
|
||||
.PARAMETER DstPool
|
||||
The name of the destination vSphere Resource Pool
|
||||
.PARAMETER DstFolder
|
||||
The name of the destination vSphere Folder
|
||||
.PARAMETER DstDatastore
|
||||
The name of the destination Datastore
|
||||
.PARAMETER DstHost
|
||||
The name of the destination host. Set to null if DstCluster is defined
|
||||
.PARAMETER srcVMs
|
||||
List of VMs to migrate
|
||||
.PARAMETER NetworkMapping
|
||||
Hash table of the VM network mappings between your source and destination vCenter Server
|
||||
.EXAMPLE
|
||||
New-XVCMRequest -opType Relocate -SrcSite SiteA -DstSite SiteB `
|
||||
-SrcDatacenter Datacenter-SiteA -DstDatacenter Datacenter-SiteB `
|
||||
-DstCluster $null -DstHost VMhost1.test.lab `
|
||||
-DstDatastore vsanDatastore `
|
||||
-srcVMs @("PhotonOS-01","PhotonOS-02","PhotonOS-03","PhotonOS-04") `
|
||||
-NetworkMapping @{"DVPG-VM Network 1"="DVPG-Internal Network";"DVPG-VM Network 2"="DVPG-External Network"}
|
||||
.EXAMPLE
|
||||
New-XVCMRequest -opType Clone -SrcSite OREGON -DstSite CALIF `
|
||||
-SrcDatacenter SDDC-Datacenter -srcVMs @(“DUDE-ubuntu”) `
|
||||
-DstDatacenter SDDC-Datacenter `
|
||||
-DstCluster "Cluster-1" -DstHost $null `
|
||||
-DstPool Compute-ResourcePool `
|
||||
-DstFolder Workloads `
|
||||
-DstDatastore WorkloadDatastore `
|
||||
-NetworkMapping @{"OREGON-VMs-sddc"="CALIF-sddc-VMs"}
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$opType, #Added by CPM for 2.0
|
||||
[Parameter(Mandatory=$true)][String]$SrcSite,
|
||||
[Parameter(Mandatory=$true)][String]$DstSite,
|
||||
[Parameter(Mandatory=$true)][String]$SrcDatacenter,
|
||||
[Parameter(Mandatory=$true)][String]$DstDatacenter,
|
||||
[Parameter(Mandatory=$true)][AllowNull()] $DstCluster, #Added [AllowNull()], removed [String] by CPM for 2.0
|
||||
[Parameter(Mandatory=$true)][String]$DstPool,
|
||||
[Parameter(Mandatory=$true)][String]$DstFolder,
|
||||
[Parameter(Mandatory=$true)][String]$DstDatastore,
|
||||
[Parameter(Mandatory=$true)][AllowNull()] $DstHost, #Added by CPM for 2.0
|
||||
[Parameter(Mandatory=$true)][String[]]$srcVMs,
|
||||
[Parameter(Mandatory=$true)][Hashtable]$NetworkMapping
|
||||
)
|
||||
|
||||
$Uri = "http://localhost:8080/api/tasks"
|
||||
|
||||
$body = @{
|
||||
"sourceSite"=$SrcSite;
|
||||
"targetSite"=$DstSite;
|
||||
"sourceDatacenter"=$SrcDatacenter;
|
||||
"targetDatacenter"=$dstDatacenter;
|
||||
"targetPool"=$DstPool;
|
||||
"targetFolder"=$DstFolder;
|
||||
"targetCluster"=$DstCluster;
|
||||
"targetDatastore"=$DstDatastore;
|
||||
"targetHost"=$DstHost; #Added by CPM for 2.0
|
||||
"networkMap"=$NetworkMapping;
|
||||
"vmList"=$srcVMs;
|
||||
"operationType"=$opType; #Added by CPM for 2.0
|
||||
}
|
||||
|
||||
$body = $body | ConvertTo-Json
|
||||
|
||||
Write-Host -ForegroundColor Cyan "Initiating migration request ..."
|
||||
$results = Invoke-WebRequest -Uri $Uri -Method POST -Body $body -ContentType "application/json"
|
||||
|
||||
if($results.StatusCode -eq 200) {
|
||||
$taskId = ($results.Content | ConvertFrom-Json).requestId
|
||||
Write-Host -ForegroundColor Green "Successfully issued migration with TaskID: $taskId"
|
||||
} else { Write-Host -ForegroundColor Red "Failed to initiate migration request" }
|
||||
}
|
||||
|
||||
Function Get-XVCMTask {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function retrieves either all migration tasks and/or a specific migration task
|
||||
.PARAMETER Id
|
||||
The task ID returned from initiating a migration
|
||||
.EXAMPLE
|
||||
Get-XVCMTask -Id <Task ID>
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$false)][String]$Id
|
||||
)
|
||||
|
||||
$Uri = "http://localhost:8080/api/tasks"
|
||||
|
||||
if($Id) {
|
||||
$body = @{"requestId"=$Id}
|
||||
|
||||
$results = Invoke-WebRequest -Uri $Uri -Method GET -Body $body -ContentType "application/json"
|
||||
} else {
|
||||
$results = Invoke-WebRequest -Uri $Uri -Method GET
|
||||
}
|
||||
|
||||
if($results.StatusCode -eq 200) {
|
||||
$results.Content | ConvertFrom-Json
|
||||
} else { Write-Host -ForegroundColor Red "Failed to retrieve tasks" }
|
||||
}
|
||||
|
||||
Function Get-VMNetwork {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function returns the list of all VM Networks attached to
|
||||
given VMs to help with initiating migration
|
||||
.PARAMETER srcVMs
|
||||
List of VMs to query their current VM Networks
|
||||
.EXAMPLE
|
||||
Get-VMNetwork -srcVMs @("PhotonOS-01","PhotonOS-02","PhotonOS-03","PhotonOS-04")
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$false)][String[]]$srcVMs
|
||||
)
|
||||
|
||||
if (-not $global:DefaultVIServers) { Write-Host -ForegroundColor red "No vCenter Server Connection found, please connect to your source vCenter Server using Connect-VIServer"; break }
|
||||
|
||||
$results = @()
|
||||
if($srcVMs) {
|
||||
foreach ($srcVM in $srcVMs) {
|
||||
$vm = Get-VM -Name $srcVM
|
||||
$networkDetails = $vm | Get-NetworkAdapter
|
||||
$tmp = [pscustomobject] @{
|
||||
Name = $srcVM;
|
||||
Adapter = $networkDetails.name;
|
||||
Network = $networkDetails.NetworkName;
|
||||
}
|
||||
$results+=$tmp
|
||||
}
|
||||
} else {
|
||||
foreach ($vm in Get-VM) {
|
||||
$networkDetails = $vm | Get-NetworkAdapter
|
||||
$tmp = [pscustomobject] @{
|
||||
Name = $vm.Name;
|
||||
Adapter = $networkDetails.name;
|
||||
Network = $networkDetails.NetworkName;
|
||||
}
|
||||
$results+=$tmp
|
||||
}
|
||||
}
|
||||
$results
|
||||
}
|
||||
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-object | 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-Object CreatedTime, @{N='Cluster';E={$_.ComputeResource.Name}}, @{Name="VMName";Expression={$_.vm.name}}, UserName, @{N='Type';E={$_.GetType().Name}}, FullFormattedMessage
|
||||
$sortedResult | where-object {$_.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
|
||||
}
|
||||
|
||||
}
|
||||
98
Modules/InstantClone/InstantClone.psm1
Normal file
98
Modules/InstantClone/InstantClone.psm1
Normal file
@@ -0,0 +1,98 @@
|
||||
Function New-InstantClone {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Apr 29, 2018
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function demonstrates the use of the new "Parentless" Instant Clone
|
||||
API that was introduced in vSphere 6.7
|
||||
.DESCRIPTION
|
||||
Function to create new "Parentless" Instant Clones in vSphere 6.7
|
||||
.EXAMPLE
|
||||
$SourceVM = "Foo"
|
||||
$newVMName = Foo-IC-1
|
||||
$guestCustomizationValues = @{
|
||||
"guestinfo.ic.hostname" = $newVMName
|
||||
"guestinfo.ic.ipaddress" = "192.168.30.10"
|
||||
"guestinfo.ic.netmask" = "255.255.255.0"
|
||||
"guestinfo.ic.gateway" = "192.168.30.1"
|
||||
"guestinfo.ic.dns" = "192.168.30.1"
|
||||
}
|
||||
New-InstantClone -SourceVM $SourceVM -DestinationVM $newVMName -CustomizationFields $guestCustomizationValues
|
||||
.NOTES
|
||||
Make sure that you have both a vSphere 6.7 env (VC/ESXi) as well as
|
||||
as the latest PowerCLI 10.1 installed which is reuqired to use vSphere 6.7 APIs
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$SourceVM,
|
||||
[Parameter(Mandatory=$true)][String]$DestinationVM,
|
||||
[Parameter(Mandatory=$true)][Hashtable]$CustomizationFields
|
||||
)
|
||||
$vm = Get-VM -Name $SourceVM
|
||||
|
||||
$config = @()
|
||||
$CustomizationFields.GetEnumerator() | Foreach-Object {
|
||||
$optionValue = New-Object VMware.Vim.OptionValue
|
||||
$optionValue.Key = $_.Key
|
||||
$optionValue.Value = $_.Value
|
||||
$config += $optionValue
|
||||
}
|
||||
|
||||
# SourceVM must either be running or running but in Frozen State
|
||||
if($vm.PowerState -ne "poweredOn") {
|
||||
Write-Host -ForegroundColor Red "Instant Cloning is only supported on a PoweredOn or Frozen VM"
|
||||
break
|
||||
}
|
||||
|
||||
# SourceVM == Powered On
|
||||
if((Get-VM $SourceVM).ExtensionData.Runtime.InstantCloneFrozen -eq $false) {
|
||||
|
||||
# Retrieve all Network Adapters for SourceVM
|
||||
$vmNetworkAdapters = @()
|
||||
$devices = $vm.ExtensionData.Config.Hardware.Device
|
||||
foreach ($device in $devices) {
|
||||
if($device -is [VMware.Vim.VirtualEthernetCard]) {
|
||||
$vmNetworkAdapters += $device
|
||||
}
|
||||
}
|
||||
|
||||
$spec = New-Object VMware.Vim.VirtualMachineInstantCloneSpec
|
||||
$locationSpec = New-Object VMware.Vim.VirtualMachineRelocateSpec
|
||||
|
||||
# Disconect all NICs for new Instant Clone to ensure no dupe addresses on network
|
||||
# post-Instant Clone workflow needs to renable after uypdating GuestOS
|
||||
foreach ($vmNetworkAdapter in $vmNetworkAdapters) {
|
||||
$networkName = $vmNetworkAdapter.backing.deviceName
|
||||
$deviceConfigSpec = New-Object VMware.Vim.VirtualDeviceConfigSpec
|
||||
$deviceConfigSpec.Operation = "edit"
|
||||
$deviceConfigSpec.Device = $vmNetworkAdapter
|
||||
$deviceConfigSpec.Device.backing = New-Object VMware.Vim.VirtualEthernetCardNetworkBackingInfo
|
||||
$deviceConfigSpec.device.backing.deviceName = $networkName
|
||||
$connectable = New-Object VMware.Vim.VirtualDeviceConnectInfo
|
||||
$connectable.MigrateConnect = "disconnect"
|
||||
$deviceConfigSpec.Device.Connectable = $connectable
|
||||
$locationSpec.DeviceChange += $deviceConfigSpec
|
||||
}
|
||||
|
||||
$spec.Config = $config
|
||||
$spec.Location = $locationSpec
|
||||
$spec.Name = $DestinationVM
|
||||
# SourceVM == Frozen
|
||||
} else {
|
||||
$spec = New-Object VMware.Vim.VirtualMachineInstantCloneSpec
|
||||
$locationSpec = New-Object VMware.Vim.VirtualMachineRelocateSpec
|
||||
$spec.Config = $config
|
||||
$spec.Location = $locationSpec
|
||||
$spec.Name = $DestinationVM
|
||||
}
|
||||
|
||||
Write-Host "Creating Instant Clone $DestinationVM ..."
|
||||
$task = $vm.ExtensionData.InstantClone_Task($spec)
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task | Out-Null
|
||||
}
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
50
Modules/NSXT/NSXT.psd1
Normal file
50
Modules/NSXT/NSXT.psd1
Normal file
@@ -0,0 +1,50 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
@{
|
||||
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-NSXTBGPNeighbors',
|
||||
'Get-NSXTComputeManager',
|
||||
'Get-NSXTController',
|
||||
'Get-NSXTEdgeCluster',
|
||||
'Get-NSXTFabricNode',
|
||||
'Get-NSXTFabricVM',
|
||||
'Get-NSXTFirewallRule',
|
||||
'Get-NSXTForwardingTable',
|
||||
'Get-NSXTIPPool',
|
||||
'Get-NSXTLogicalRouter',
|
||||
'Get-NSXTLogicalRouterPorts',
|
||||
'Get-NSXTLogicalSwitch',
|
||||
'Get-NSXTManager',
|
||||
'Get-NSXTNetworkRoutes',
|
||||
'Get-NSXTRoutingTable',
|
||||
'Get-NSXTTraceFlow',
|
||||
'Get-NSXTTraceFlowObservations',
|
||||
'Get-NSXTTransportNode',
|
||||
'Get-NSXTTransportZone',
|
||||
'Get-NSXTClusterNode',
|
||||
'Set-NSXTIPPool',
|
||||
'Set-NSXTLogicalRouter',
|
||||
'Set-NSXTLogicalSwitch',
|
||||
'Set-NSXTTraceFlow',
|
||||
'Get-NSXTIPAMIPBlock',
|
||||
'Set-NSXTIPAMIPBlock',
|
||||
'Remove-NSXTIPAMIPBlock'
|
||||
|
||||
|
||||
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'
|
||||
}
|
||||
}
|
||||
}
|
||||
2108
Modules/NSXT/NSXT.psm1
Normal file
2108
Modules/NSXT/NSXT.psm1
Normal file
File diff suppressed because it is too large
Load Diff
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
|
||||
}
|
||||
}
|
||||
}
|
||||
196
Modules/PerVMEVC/PerVMEVC.psm1
Normal file
196
Modules/PerVMEVC/PerVMEVC.psm1
Normal file
@@ -0,0 +1,196 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
function Get-VMEvcMode {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Gathers information on the EVC status of a VM
|
||||
.DESCRIPTION
|
||||
Will provide the EVC status for the specified VM
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy, thatcouldbeaproblem.com
|
||||
.PARAMETER Name
|
||||
VM name which the function should be ran against
|
||||
.EXAMPLE
|
||||
Get-VMEvcMode -Name vmName
|
||||
Retreives the EVC status of the provided VM
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
$Name
|
||||
)
|
||||
|
||||
Process {
|
||||
$evVM = @()
|
||||
|
||||
if ($name -is [string]) {$evVM += Get-VM -Name $Name -ErrorAction SilentlyContinue}
|
||||
elseif ($name -is [array]) {
|
||||
|
||||
if ($name[0] -is [string]) {
|
||||
$name | foreach {
|
||||
$evVM += Get-VM -Name $_ -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
elseif ($name[0] -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]) {$evVM = $name}
|
||||
|
||||
}
|
||||
elseif ($name -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]) {$evVM += $name}
|
||||
|
||||
if ($evVM -eq $null) {Write-Warning "No VMs found."}
|
||||
else {
|
||||
$output = @()
|
||||
foreach ($v in $evVM) {
|
||||
|
||||
$report = "" | select Name,EVCMode
|
||||
$report.Name = $v.Name
|
||||
$report.EVCMode = $v.ExtensionData.Runtime.MinRequiredEVCModeKey
|
||||
$output += $report
|
||||
|
||||
}
|
||||
|
||||
return $output
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function Remove-VMEvcMode {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Removes the EVC status of a VM
|
||||
.DESCRIPTION
|
||||
Will remove the EVC status for the specified VM
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy, thatcouldbeaproblem.com
|
||||
.PARAMETER Name
|
||||
VM name which the function should be ran against
|
||||
.EXAMPLE
|
||||
Remove-VMEvcMode -Name vmName
|
||||
Removes the EVC status of the provided VM
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
$Name
|
||||
)
|
||||
|
||||
Process {
|
||||
$evVM = @()
|
||||
$updateVM = @()
|
||||
|
||||
if ($name -is [string]) {$evVM += Get-VM -Name $Name -ErrorAction SilentlyContinue}
|
||||
elseif ($name -is [array]) {
|
||||
|
||||
if ($name[0] -is [string]) {
|
||||
$name | foreach {
|
||||
$evVM += Get-VM -Name $_ -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
elseif ($name[0] -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]) {$evVM = $name}
|
||||
|
||||
}
|
||||
elseif ($name -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]) {$evVM += $name}
|
||||
|
||||
if ($evVM -eq $null) {Write-Warning "No VMs found."}
|
||||
else {
|
||||
foreach ($v in $evVM) {
|
||||
|
||||
if (($v.HardwareVersion -ge 'vmx-14' -and $v.PowerState -eq 'PoweredOff') -or ($v.Version -ge 'v14' -and $v.PowerState -eq 'PoweredOff')) {
|
||||
|
||||
$v.ExtensionData.ApplyEvcModeVM_Task($null, $true) | Out-Null
|
||||
$updateVM += $v.Name
|
||||
|
||||
}
|
||||
else {Write-Warning $v.Name + " does not have the minimum requirements of being Hardware Version 14 and powered off."}
|
||||
|
||||
}
|
||||
|
||||
if ($updateVM) {
|
||||
|
||||
Start-Sleep -Seconds 2
|
||||
Get-VMEvcMode -Name $updateVM
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function Set-VMEvcMode {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Configures the EVC status of a VM
|
||||
.DESCRIPTION
|
||||
Will configure the EVC status for the specified VM
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy, thatcouldbeaproblem.com
|
||||
.PARAMETER Name
|
||||
VM name which the function should be ran against
|
||||
.PARAMETER EvcMode
|
||||
The EVC Mode key which should be set
|
||||
.EXAMPLE
|
||||
Set-VMEvcMode -Name vmName -EvcMode intel-sandybridge
|
||||
Configures the EVC status of the provided VM to be 'intel-sandybridge'
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
$Name,
|
||||
[Parameter(Mandatory=$true,Position=1)]
|
||||
[ValidateSet("intel-merom","intel-penryn","intel-nehalem","intel-westmere","intel-sandybridge","intel-ivybridge","intel-haswell","intel-broadwell","intel-skylake","amd-rev-e","amd-rev-f","amd-greyhound-no3dnow","amd-greyhound","amd-bulldozer","amd-piledriver","amd-steamroller","amd-zen")]
|
||||
$EvcMode
|
||||
)
|
||||
|
||||
Process {
|
||||
$evVM = @()
|
||||
$updateVM = @()
|
||||
|
||||
if ($name -is [string]) {$evVM += Get-VM -Name $Name -ErrorAction SilentlyContinue}
|
||||
elseif ($name -is [array]) {
|
||||
|
||||
if ($name[0] -is [string]) {
|
||||
$name | foreach {
|
||||
$evVM += Get-VM -Name $_ -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
elseif ($name[0] -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]) {$evVM = $name}
|
||||
|
||||
}
|
||||
elseif ($name -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]) {$evVM += $name}
|
||||
|
||||
if ($evVM -eq $null) {Write-Warning "No VMs found."}
|
||||
else {
|
||||
|
||||
$si = Get-View ServiceInstance
|
||||
$evcMask = $si.Capability.SupportedEvcMode | where-object {$_.key -eq $EvcMode} | select -ExpandProperty FeatureMask
|
||||
|
||||
foreach ($v in $evVM) {
|
||||
|
||||
if (($v.HardwareVersion -ge 'vmx-14' -and $v.PowerState -eq 'PoweredOff') -or ($v.Version -ge 'v14' -and $v.PowerState -eq 'PoweredOff')) {
|
||||
|
||||
$v.ExtensionData.ApplyEvcModeVM_Task($evcMask, $true) | Out-Null
|
||||
$updateVM += $v.Name
|
||||
|
||||
}
|
||||
else {Write-Warning $v.Name + " does not have the minimum requirements of being Hardware Version 14 and powered off."}
|
||||
|
||||
}
|
||||
|
||||
if ($updateVM) {
|
||||
|
||||
Start-Sleep -Seconds 2
|
||||
Get-VMEvcMode -Name $updateVM
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
472
Modules/ProactiveHA/ProactiveHA.psm1
Normal file
472
Modules/ProactiveHA/ProactiveHA.psm1
Normal file
@@ -0,0 +1,472 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
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
|
||||
}
|
||||
}
|
||||
231
Modules/Recommend-Sizing/Recommend-Sizing.psm1
Normal file
231
Modules/Recommend-Sizing/Recommend-Sizing.psm1
Normal file
@@ -0,0 +1,231 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
1
Modules/SRM/.gitattributes
vendored
Normal file
1
Modules/SRM/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.psd1 diff
|
||||
1
Modules/SRM/.gitignore
vendored
Normal file
1
Modules/SRM/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.zip
|
||||
176
Modules/SRM/Examples/ReportConfiguration.ps1
Normal file
176
Modules/SRM/Examples/ReportConfiguration.ps1
Normal file
@@ -0,0 +1,176 @@
|
||||
<#
|
||||
Copyright 2017-2021 VMware, Inc.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
#>
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
|
||||
# Depends on SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
|
||||
# It is assumed that the connection to VC and SRM Server have already been made
|
||||
|
||||
Function Get-SrmConfigReportSite {
|
||||
Param(
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
Get-SrmServer $SrmServer |
|
||||
Format-Table -Wrap -AutoSize @{Label="SRM Site Name"; Expression={$_.ExtensionData.GetSiteName()} },
|
||||
@{Label="SRM Host"; Expression={$_.Name} },
|
||||
@{Label="SRM Port"; Expression={$_.Port} },
|
||||
@{Label="Version"; Expression={$_.Version} },
|
||||
@{Label="Build"; Expression={$_.Build} },
|
||||
@{Label="SRM Peer Site Name"; Expression={$_.ExtensionData.GetPairedSite().Name} }
|
||||
}
|
||||
|
||||
Function Get-SrmConfigReportPlan {
|
||||
Param(
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
Get-SrmRecoveryPlan -SrmServer $SrmServer | %{
|
||||
$rp = $_
|
||||
$rpinfo = $rp.GetInfo()
|
||||
$peerState = $rp.GetPeer().State
|
||||
$pgs = Get-SrmProtectionGroup -RecoveryPlan $rp
|
||||
$pgnames = $pgs | %{ $_.GetInfo().Name }
|
||||
|
||||
$output = "" | select plan, state, peerState, groups
|
||||
$output.plan = $rpinfo.Name
|
||||
$output.state = $rpinfo.State
|
||||
$output.peerState = $peerState
|
||||
if ($pgnames) {
|
||||
$output.groups = [string]::Join(",`r`n", $pgnames)
|
||||
} else {
|
||||
$output.groups = "NONE"
|
||||
}
|
||||
|
||||
$output
|
||||
} | Format-Table -Wrap -AutoSize @{Label="Recovery Plan Name"; Expression={$_.plan} },
|
||||
@{Label="Recovery State"; Expression={$_.state} },
|
||||
@{Label="Peer Recovery State"; Expression={$_.peerState} },
|
||||
@{Label="Protection Groups"; Expression={$_.groups}}
|
||||
}
|
||||
|
||||
|
||||
Function Get-SrmConfigReportProtectionGroup {
|
||||
Param(
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
Get-SrmProtectionGroup -SrmServer $SrmServer | %{
|
||||
$pg = $_
|
||||
$pginfo = $pg.GetInfo()
|
||||
$pgstate = $pg.GetProtectionState()
|
||||
$peerState = $pg.GetPeer().State
|
||||
$rps = Get-SrmRecoveryPlan -ProtectionGroup $pg
|
||||
$rpnames = $rps | %{ $_.GetInfo().Name }
|
||||
|
||||
$output = "" | select name, type, state, peerState, plans
|
||||
$output.name = $pginfo.Name
|
||||
$output.type = $pginfo.Type
|
||||
$output.state = $pgstate
|
||||
$output.peerState = $peerState
|
||||
if ($rpnames) {
|
||||
$output.plans = [string]::Join(",`r`n", $rpnames)
|
||||
} else {
|
||||
$output.plans = "NONE"
|
||||
}
|
||||
|
||||
$output
|
||||
} | Format-Table -Wrap -AutoSize @{Label="Protection Group Name"; Expression={$_.name} },
|
||||
@{Label="Type"; Expression={$_.type} },
|
||||
@{Label="Protection State"; Expression={$_.state} },
|
||||
@{Label="Peer Protection State"; Expression={$_.peerState} },
|
||||
@{Label="Recovery Plans"; Expression={$_.plans} }
|
||||
}
|
||||
|
||||
|
||||
Function Get-SrmConfigReportProtectedDatastore {
|
||||
Param(
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
Get-SrmProtectionGroup -SrmServer $SrmServer -Type "san" | %{
|
||||
$pg = $_
|
||||
$pginfo = $pg.GetInfo()
|
||||
$pds = Get-SrmProtectedDatastore -ProtectionGroup $pg
|
||||
$pds | %{
|
||||
$pd = $_
|
||||
$output = "" | select datacenter, group, name, capacity, free
|
||||
$output.datacenter = $pd.Datacenter.Name
|
||||
$output.group = $pginfo.Name
|
||||
$output.name = $pd.Name
|
||||
$output.capacity = $pd.CapacityGB
|
||||
$output.free = $pd.FreeSpaceGB
|
||||
|
||||
$output
|
||||
|
||||
}
|
||||
} | Format-Table -Wrap -AutoSize -GroupBy "datacenter" @{Label="Datastore Name"; Expression={$_.name} },
|
||||
@{Label="Capacity GB"; Expression={$_.capacity} },
|
||||
@{Label="Free GB"; Expression={$_.free} },
|
||||
@{Label="Protection Group"; Expression={$_.group} }
|
||||
}
|
||||
|
||||
|
||||
Function Get-SrmConfigReportProtectedVm {
|
||||
Param(
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$srmversion = Get-SrmServerVersion -SrmServer $SrmServer
|
||||
$srmMajorVersion, $srmMinorVersion = $srmversion -split "\."
|
||||
|
||||
Get-SrmProtectionGroup -SrmServer $SrmServer | %{
|
||||
$pg = $_
|
||||
$pginfo = $pg.GetInfo()
|
||||
$pvms = Get-SrmProtectedVM -ProtectionGroup $pg
|
||||
$rps = Get-SrmRecoveryPlan -ProtectionGroup $pg
|
||||
$rpnames = $rps | %{ $_.GetInfo().Name }
|
||||
$pvms | %{
|
||||
$pvm = $_
|
||||
if ($srmMajorVersion -ge 6 -or ($srmMajorVersion -eq 5 -and $srmMinorVersion -eq 8)) {
|
||||
$rs = $rps | Select -First 1 | %{ $_.GetRecoverySettings($pvm.Vm.MoRef) }
|
||||
}
|
||||
$output = "" | select group, name, moRef, needsConfiguration, state, plans, priority, finalPowerState, preCallouts, postCallouts
|
||||
$output.group = $pginfo.Name
|
||||
$output.name = $pvm.Vm.Name
|
||||
$output.moRef = $pvm.Vm.MoRef # this is necessary in case we can't retrieve the name when VC is unavailable
|
||||
$output.needsConfiguration = $pvm.NeedsConfiguration
|
||||
$output.state = $pvm.State
|
||||
$output.plans = [string]::Join(",`r`n", $rpnames)
|
||||
if ($rs) {
|
||||
$output.priority = $rs.RecoveryPriority
|
||||
$output.finalPowerState = $rs.FinalPowerState
|
||||
$output.preCallouts = $rs.PrePowerOnCallouts.Count
|
||||
$output.postCallouts = $rs.PostPowerOnCallouts.Count
|
||||
}
|
||||
$output
|
||||
|
||||
}
|
||||
} | Format-Table -Wrap -AutoSize @{Label="VM Name"; Expression={$_.name} },
|
||||
@{Label="VM MoRef"; Expression={$_.moRef} },
|
||||
@{Label="Needs Config"; Expression={$_.needsConfiguration} },
|
||||
@{Label="VM Protection State"; Expression={$_.state} },
|
||||
@{Label="Protection Group"; Expression={$_.group} },
|
||||
@{Label="Recovery Plans"; Expression={$_.plans} },
|
||||
@{Label="Recovery Priority"; Expression={$_.priority} },
|
||||
@{Label="Final Power State"; Expression={$_.finalPowerState} },
|
||||
@{Label="Pre-PowerOn Callouts"; Expression={$_.preCallouts} },
|
||||
@{Label="Post-PowerOn Callouts"; Expression={$_.postCallouts} }
|
||||
|
||||
}
|
||||
|
||||
Function Get-SrmConfigReport {
|
||||
Param(
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
Get-SrmConfigReportSite -SrmServer $SrmServer
|
||||
Get-SrmConfigReportPlan -SrmServer $SrmServer
|
||||
Get-SrmConfigReportProtectionGroup -SrmServer $SrmServer
|
||||
Get-SrmConfigReportProtectedDatastore -SrmServer $SrmServer
|
||||
Get-SrmConfigReportProtectedVm -SrmServer $SrmServer
|
||||
}
|
||||
43
Modules/SRM/Examples/SrmTagging.ps1
Normal file
43
Modules/SRM/Examples/SrmTagging.ps1
Normal file
@@ -0,0 +1,43 @@
|
||||
<#
|
||||
Copyright 2017-2021 VMware, Inc.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
#>
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
|
||||
# Depends on SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
|
||||
# It is assumed that the connections to active VC and SRM Server have already been made
|
||||
|
||||
Import-Module Meadowcroft.SRM -Prefix Srm
|
||||
|
||||
$TagCategoryName = 'Meadowcroft.SRM.VM'
|
||||
$TagCategoryDescription = 'Tag category for tagging VMs with SRM state'
|
||||
|
||||
# If the tag category doesn't exist, create it and the relevant tags
|
||||
$TagCategory = Get-TagCategory -Name $TagCategoryName -ErrorAction SilentlyContinue
|
||||
if (-Not $TagCategory) {
|
||||
Write-Output "Creating Tag Category $TagCategoryName"
|
||||
$TagCategory = New-TagCategory -Name $TagCategoryName -Description $TagCategoryDescription -EntityType 'VirtualMachine'
|
||||
|
||||
Write-Output "Creating Tag SrmProtectedVm"
|
||||
New-Tag -Name 'SrmProtectedVm' -Category $TagCategory -Description "VM protected by VMware SRM"
|
||||
Write-Output "Creating Tag SrmTestVm"
|
||||
New-Tag -Name 'SrmTestVm' -Category $TagCategory -Description "Test VM instantiated by VMware SRM"
|
||||
Write-Output "Creating Tag SrmPlaceholderVm"
|
||||
New-Tag -Name 'SrmPlaceholderVm' -Category $TagCategory -Description "Placeholder VM used by VMware SRM"
|
||||
}
|
||||
|
||||
$protectedVmTag = Get-Tag -Name 'SrmProtectedVm' -Category $TagCategory
|
||||
$testVmTag = Get-Tag -Name 'SrmTestVm' -Category $TagCategory
|
||||
$placeholderVmTag = Get-Tag -Name 'SrmPlaceholderVm' -Category $TagCategory
|
||||
|
||||
# Assign protected tag to a VM, use ready state to get "local" protected VMs
|
||||
Get-SrmProtectedVM -State Ready | %{ New-TagAssignment -Tag $protectedVmTag -Entity $(Get-VIObjectByVIView $_.Vm) | Out-Null }
|
||||
|
||||
# Assign test tag to a VM
|
||||
Get-SrmTestVM | %{ New-TagAssignment -Tag $testVmTag -Entity $_ | Out-Null }
|
||||
|
||||
# Assign placeholder tag to a VM
|
||||
Get-SrmPlaceholderVM | %{ New-TagAssignment -Tag $placeholderVmTag -Entity $_ | Out-Null }
|
||||
74
Modules/SRM/LICENSE.txt
Normal file
74
Modules/SRM/LICENSE.txt
Normal file
@@ -0,0 +1,74 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
||||
|
||||
Copyright 2017-2021 VMware, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied.
|
||||
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
431
Modules/SRM/Meadowcroft.Srm.Protection.ps1
Normal file
431
Modules/SRM/Meadowcroft.Srm.Protection.ps1
Normal file
@@ -0,0 +1,431 @@
|
||||
<#
|
||||
Copyright 2017-2021 VMware, Inc.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
#>
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
|
||||
# SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the subset of protection groups matching the input criteria
|
||||
|
||||
.PARAMETER Name
|
||||
Return protection groups matching the specified name
|
||||
|
||||
.PARAMETER Type
|
||||
Return protection groups matching the specified protection group
|
||||
type. For SRM 5.0-5.5 this is either 'san' for protection groups
|
||||
consisting of a set of replicated datastores or 'vr' for vSphere
|
||||
Replication based protection groups.
|
||||
|
||||
.PARAMETER RecoveryPlan
|
||||
Return protection groups associated with a particular recovery
|
||||
plan
|
||||
|
||||
.PARAMETER SrmServer
|
||||
the SRM server to use for this operation.
|
||||
#>
|
||||
Function Get-ProtectionGroup {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter(position=1)][string] $Name,
|
||||
[string] $Type,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan[]] $RecoveryPlan,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
begin {
|
||||
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
|
||||
$pgs = @()
|
||||
}
|
||||
process {
|
||||
if ($RecoveryPlan) {
|
||||
foreach ($rp in $RecoveryPlan) {
|
||||
$pgs += $RecoveryPlan.GetInfo().ProtectionGroups
|
||||
}
|
||||
$pgs = Select_UniqueByMoRef($pgs)
|
||||
} else {
|
||||
$pgs += $api.Protection.ListProtectionGroups()
|
||||
}
|
||||
}
|
||||
end {
|
||||
$pgs | ForEach-Object {
|
||||
$pg = $_
|
||||
$pgi = $pg.GetInfo()
|
||||
$selected = (-not $Name -or ($Name -eq $pgi.Name)) -and (-not $Type -or ($Type -eq $pgi.Type))
|
||||
if ($selected) {
|
||||
Add-Member -InputObject $pg -MemberType NoteProperty -Name "Name" -Value $pgi.Name
|
||||
$pg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the subset of protected VMs matching the input criteria
|
||||
|
||||
.PARAMETER Name
|
||||
Return protected VMs matching the specified name
|
||||
|
||||
.PARAMETER State
|
||||
Return protected VMs matching the specified state. For protected
|
||||
VMs on the protected site this is usually 'ready', for
|
||||
placeholder VMs this is 'shadowing'
|
||||
|
||||
.PARAMETER ProtectionGroup
|
||||
Return protected VMs associated with particular protection
|
||||
groups
|
||||
#>
|
||||
Function Get-ProtectedVM {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter(position=1)][string] $Name,
|
||||
[VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectionState] $State,
|
||||
[VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectionState] $PeerState,
|
||||
[switch] $ConfiguredOnly,
|
||||
[switch] $UnconfiguredOnly,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup[]] $ProtectionGroup,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan[]] $RecoveryPlan,
|
||||
[string] $ProtectionGroupName,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
if ($null -eq $ProtectionGroup) {
|
||||
$ProtectionGroup = Get-ProtectionGroup -Name $ProtectionGroupName -RecoveryPlan $RecoveryPlan -SrmServer $SrmServer
|
||||
}
|
||||
$ProtectionGroup | ForEach-Object {
|
||||
$pg = $_
|
||||
$pg.ListProtectedVms() | ForEach-Object {
|
||||
# try and update the view data for the protected VM
|
||||
try {
|
||||
$_.Vm.UpdateViewData()
|
||||
} catch {
|
||||
Write-Error $_
|
||||
} finally {
|
||||
$_
|
||||
}
|
||||
} | Where-object { -not $Name -or ($Name -eq $_.Vm.Name) } |
|
||||
where-object { -not $State -or ($State -eq $_.State) } |
|
||||
where-object { -not $PeerState -or ($PeerState -eq $_.PeerState) } |
|
||||
where-object { ($ConfiguredOnly -and $_.NeedsConfiguration -eq $false) -or ($UnconfiguredOnly -and $_.NeedsConfiguration -eq $true) -or (-not $ConfiguredOnly -and -not $UnconfiguredOnly) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the unprotected VMs that are associated with a protection group
|
||||
|
||||
.PARAMETER ProtectionGroup
|
||||
Return unprotected VMs associated with particular protection
|
||||
groups. For VR protection groups this is VMs that are associated
|
||||
with the PG but not configured, For ABR protection groups this is
|
||||
VMs on replicated datastores associated with the group that are not
|
||||
configured.
|
||||
#>
|
||||
Function Get-UnProtectedVM {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup[]] $ProtectionGroup,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan[]] $RecoveryPlan,
|
||||
[string] $ProtectionGroupName,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
if ($null -eq $ProtectionGroup) {
|
||||
$ProtectionGroup = Get-ProtectionGroup -Name $ProtectionGroupName -RecoveryPlan $RecoveryPlan -SrmServer $SrmServer
|
||||
}
|
||||
|
||||
$associatedVMs = @()
|
||||
$protectedVmRefs = @()
|
||||
|
||||
$ProtectionGroup | ForEach-Object {
|
||||
$pg = $_
|
||||
# For VR listAssociatedVms to get list of VMs
|
||||
if ($pg.GetInfo().Type -eq 'vr') {
|
||||
$associatedVMs += @($pg.ListAssociatedVms() | Get-VIObjectByVIView)
|
||||
}
|
||||
# TODO test this: For ABR get VMs on GetProtectedDatastore
|
||||
if ($pg.GetInfo().Type -eq 'san') {
|
||||
$pds = @(Get-ProtectedDatastore -ProtectionGroup $pg)
|
||||
$pds | ForEach-Object {
|
||||
$ds = Get-Datastore -id $_.MoRef
|
||||
$associatedVMs += @(Get-VM -Datastore $ds)
|
||||
}
|
||||
}
|
||||
|
||||
# get protected VMs
|
||||
$protectedVmRefs += @(Get-ProtectedVM -ProtectionGroup $pg | ForEach-Object { $_.Vm.MoRef } | Select-Object -Unique)
|
||||
}
|
||||
|
||||
# get associated but unprotected VMs
|
||||
$associatedVMs | Where-Object { $protectedVmRefs -notcontains $_.ExtensionData.MoRef }
|
||||
}
|
||||
|
||||
|
||||
#Untested as I don't have ABR setup in my lab yet
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the subset of protected Datastores matching the input criteria
|
||||
|
||||
.PARAMETER ProtectionGroup
|
||||
Return protected datastores associated with particular protection
|
||||
groups
|
||||
#>
|
||||
Function Get-ProtectedDatastore {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup[]] $ProtectionGroup,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan[]] $RecoveryPlan,
|
||||
[string] $ProtectionGroupName,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
if (-not $ProtectionGroup) {
|
||||
$ProtectionGroup = Get-ProtectionGroup -Name $ProtectionGroupName -RecoveryPlan $RecoveryPlan -SrmServer $SrmServer
|
||||
}
|
||||
$ProtectionGroup | ForEach-Object {
|
||||
$pg = $_
|
||||
if ($pg.GetInfo().Type -eq 'san') { # only supported for array based replication datastores
|
||||
$pg.ListProtectedDatastores()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#Untested as I don't have ABR setup in my lab yet
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the replicated datastores that aren't associated with a protection group.
|
||||
#>
|
||||
Function Get-ReplicatedDatastore {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
|
||||
|
||||
$api.Protection.ListUnassignedReplicatedDatastores()
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Protect a VM using SRM
|
||||
|
||||
.PARAMETER ProtectionGroup
|
||||
The protection group that this VM will belong to
|
||||
|
||||
.PARAMETER Vm
|
||||
The virtual machine to protect
|
||||
#>
|
||||
Function Protect-VM {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup] $ProtectionGroup,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $Vm,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.Vim.VirtualMachine] $VmView
|
||||
)
|
||||
|
||||
$moRef = Get_MoRefFromVmObj -Vm $Vm -VmView $VmView
|
||||
|
||||
$pgi = $ProtectionGroup.GetInfo()
|
||||
#TODO query protection status first
|
||||
|
||||
if ($moRef) {
|
||||
if ($pgi.Type -eq 'vr') {
|
||||
$ProtectionGroup.AssociateVms(@($moRef))
|
||||
}
|
||||
$protectionSpec = New-Object VMware.VimAutomation.Srm.Views.SrmProtectionGroupVmProtectionSpec
|
||||
$protectionSpec.Vm = $moRef
|
||||
$protectTask = $ProtectionGroup.ProtectVms($protectionSpec)
|
||||
while(-not $protectTask.IsComplete()) { Start-Sleep -Seconds 1 }
|
||||
$protectTask.GetResult()
|
||||
} else {
|
||||
throw "Can't protect the VM, no MoRef found."
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Unprotect a VM using SRM
|
||||
|
||||
.PARAMETER ProtectionGroup
|
||||
The protection group that this VM will be removed from
|
||||
|
||||
.PARAMETER Vm
|
||||
The virtual machine to unprotect
|
||||
#>
|
||||
Function Unprotect-VM {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup] $ProtectionGroup,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $Vm,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.Vim.VirtualMachine] $VmView,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectedVm] $ProtectedVm
|
||||
)
|
||||
|
||||
$moRef = Get_MoRefFromVmObj -Vm $Vm -VmView $VmView -ProtectedVm $ProtectedVm
|
||||
|
||||
$pgi = $ProtectionGroup.GetInfo()
|
||||
$protectTask = $ProtectionGroup.UnprotectVms($moRef)
|
||||
while(-not $protectTask.IsComplete()) { Start-Sleep -Seconds 1 }
|
||||
if ($pgi.Type -eq 'vr') {
|
||||
$ProtectionGroup.UnassociateVms(@($moRef))
|
||||
}
|
||||
$protectTask.GetResult()
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get a protection group folder
|
||||
|
||||
.PARAMETER SrmServer
|
||||
The SRM Server to query for the protection group folder
|
||||
#>
|
||||
Function Get-ProtectionGroupFolder {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
|
||||
|
||||
$folder = $api.Protection.GetProtectionGroupRootFolder()
|
||||
|
||||
return $folder
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a new protection group
|
||||
|
||||
.PARAMETER Name
|
||||
The name of the protection group
|
||||
|
||||
.PARAMETER Description
|
||||
Description of the protection group
|
||||
|
||||
.PARAMETER Folder
|
||||
The protection group folder in which to create the new protection group
|
||||
|
||||
.PARAMETER ArrayReplication
|
||||
Set if protection group is for replicating VMs using Array based replication
|
||||
|
||||
.PARAMETER vSphereReplication
|
||||
Set if protection group is for replicating VMs with vSphere Replication
|
||||
|
||||
.PARAMETER VMs
|
||||
For vSphere Replication based protection, the VMs to add to the replication
|
||||
group. These should already be replicated.
|
||||
|
||||
.PARAMETER VMViews
|
||||
For vSphere Replication based protection, the VMs to add to the replication
|
||||
group. These should already be replicated.
|
||||
|
||||
.PARAMETER SrmServer
|
||||
The SRM Server to perform the operation against
|
||||
#>
|
||||
Function New-ProtectionGroup {
|
||||
[cmdletbinding(DefaultParameterSetName="VR", SupportsShouldProcess=$True, ConfirmImpact="Medium")]
|
||||
[OutputType([VMware.VimAutomation.Srm.Views.SrmProtectionGroup])]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true)] $Name,
|
||||
$Description,
|
||||
[VMware.VimAutomation.Srm.Views.SrmProtectionGroupFolder] $Folder,
|
||||
[Parameter (ParameterSetName="ABR", Mandatory=$true)][switch] $ArrayReplication,
|
||||
[Parameter (ValueFromPipeline=$true, ParameterSetName="ABR")][VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.Datastore[]] $Datastores,
|
||||
[Parameter (ValueFromPipeline=$true, ParameterSetName="ABR")][VMware.Vim.Datastore[]] $DatastoreViews,
|
||||
[Parameter (ParameterSetName="VR", Mandatory=$true)][switch] $vSphereReplication,
|
||||
[Parameter (ValueFromPipeline=$true, ParameterSetName="VR")][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] $VMs,
|
||||
[Parameter (ValueFromPipeline=$true, ParameterSetName="VR")][VMware.Vim.VirtualMachine[]] $VMViews,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$api = Get-ServerApiEndpoint $SrmServer
|
||||
[VMware.VimAutomation.Srm.Views.SrmCreateProtectionGroupTask] $task = $null
|
||||
|
||||
#get root folder if this wasn't specified as a parameter
|
||||
if(-not $Folder) {
|
||||
$Folder = Get-ProtectionGroupFolder -SrmServer $SrmServer
|
||||
}
|
||||
|
||||
if ($vSphereReplication) {
|
||||
#create list of managed object references from VM and/or VM view arrays
|
||||
[VMware.Vim.ManagedObjectReference[]]$moRefs = @()
|
||||
foreach ($vm in $VMs) {
|
||||
$moRefs += Get_MoRefFromVmObj -Vm $Vm
|
||||
}
|
||||
foreach ($VmView in $VMViews) {
|
||||
$moRefs += Get_MoRefFromVmObj -VmView $VmView
|
||||
}
|
||||
|
||||
if ($pscmdlet.ShouldProcess($Name, "New")) {
|
||||
$task = $api.Protection.CreateHbrProtectionGroup($Folder.MoRef, $Name, $Description, $moRefs)
|
||||
}
|
||||
|
||||
} elseif ($ArrayReplication) {
|
||||
#create list of managed object references from VM and/or VM view arrays
|
||||
$moRefs = @()
|
||||
foreach ($ds in $Datastores) {
|
||||
$moRefs += $ds.ExtensionData.MoRef
|
||||
}
|
||||
foreach ($DsView in $DatastoreViews) {
|
||||
$moRefs += $DsView.MoRef
|
||||
}
|
||||
|
||||
if ($pscmdlet.ShouldProcess($Name, "New")) {
|
||||
$task = $api.Protection.CreateAbrProtectionGroup($Folder.MoRef, $Name, $Description, $moRefs)
|
||||
}
|
||||
|
||||
} else {
|
||||
throw "Undetermined protection group type"
|
||||
}
|
||||
|
||||
# Complete task
|
||||
while(-not $task.IsCreateProtectionGroupComplete()) { Start-Sleep -Seconds 1 }
|
||||
|
||||
# Retrieve the protection group, and protect associated VMs
|
||||
$pg = $task.GetNewProtectionGroup()
|
||||
if ($pg) {
|
||||
$unProtectedVMs = Get-UnProtectedVM -ProtectionGroup $pg
|
||||
$unProtectedVMs | Protect-VM -ProtectionGroup $pg
|
||||
}
|
||||
|
||||
return $pg
|
||||
}
|
||||
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Delete a protection group
|
||||
|
||||
.PARAMETER ProtectionGroup
|
||||
The protection group to remove
|
||||
|
||||
.PARAMETER SrmServer
|
||||
The SRM Server to perform the operation against
|
||||
#>
|
||||
Function Remove-ProtectionGroup {
|
||||
[cmdletbinding(SupportsShouldProcess=$True, ConfirmImpact="High")]
|
||||
[OutputType([VMware.VimAutomation.Srm.Views.RemoveProtectionGroupTask])]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup] $ProtectionGroup,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$api = Get-ServerApiEndpoint $SrmServer
|
||||
[VMware.VimAutomation.Srm.Views.RemoveProtectionGroupTask] $task = $null
|
||||
|
||||
$pginfo = $ProtectionGroup.GetInfo()
|
||||
if ($pscmdlet.ShouldProcess($pginfo.Name, "Remove")) {
|
||||
$task = $api.Protection.RemoveProtectionGroup($ProtectionGroup.MoRef)
|
||||
}
|
||||
|
||||
return $task
|
||||
}
|
||||
565
Modules/SRM/Meadowcroft.Srm.Recovery.ps1
Normal file
565
Modules/SRM/Meadowcroft.Srm.Recovery.ps1
Normal file
@@ -0,0 +1,565 @@
|
||||
<#
|
||||
Copyright 2017-2021 VMware, Inc.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
#>
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
|
||||
# SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the subset of recovery plans matching the input criteria
|
||||
|
||||
.PARAMETER Name
|
||||
Return recovery plans matching the specified name
|
||||
|
||||
.PARAMETER ProtectionGroup
|
||||
Return recovery plans associated with particular protection
|
||||
groups
|
||||
#>
|
||||
Function Get-RecoveryPlan {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter(position=1)][string] $Name,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup[]] $ProtectionGroup,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
begin {
|
||||
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
|
||||
$rps = @()
|
||||
}
|
||||
process {
|
||||
if ($ProtectionGroup) {
|
||||
foreach ($pg in $ProtectionGroup) {
|
||||
$rps += $pg.ListRecoveryPlans()
|
||||
}
|
||||
$rps = Select_UniqueByMoRef($rps)
|
||||
} else {
|
||||
$rps += $api.Recovery.ListPlans()
|
||||
}
|
||||
}
|
||||
end {
|
||||
$rps | ForEach-Object {
|
||||
$rp = $_
|
||||
$rpi = $rp.GetInfo()
|
||||
$selected = (-not $Name -or ($Name -eq $rpi.Name))
|
||||
if ($selected) {
|
||||
Add-Member -InputObject $rp -MemberType NoteProperty -Name "Name" -Value $rpi.Name
|
||||
$rp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Start a Recovery Plan action like test, recovery, cleanup, etc.
|
||||
|
||||
.PARAMETER RecoveryPlan
|
||||
The recovery plan to start
|
||||
|
||||
.PARAMETER RecoveryMode
|
||||
The recovery mode to invoke on the plan. May be one of "Test", "Cleanup", "Failover", "Migrate", "Reprotect"
|
||||
#>
|
||||
Function Start-RecoveryPlan {
|
||||
[cmdletbinding(SupportsShouldProcess=$True, ConfirmImpact="High")]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true, Position=1)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
|
||||
[VMware.VimAutomation.Srm.Views.SrmRecoveryPlanRecoveryMode] $RecoveryMode = [VMware.VimAutomation.Srm.Views.SrmRecoveryPlanRecoveryMode]::Test,
|
||||
[bool] $SyncData = $True
|
||||
)
|
||||
|
||||
# Validate with informative error messages
|
||||
$rpinfo = $RecoveryPlan.GetInfo()
|
||||
|
||||
# Create recovery options
|
||||
$rpOpt = New-Object VMware.VimAutomation.Srm.Views.SrmRecoveryOptions
|
||||
$rpOpt.SyncData = $SyncData
|
||||
|
||||
# Prompt the user to confirm they want to execute the action
|
||||
if ($pscmdlet.ShouldProcess($rpinfo.Name, $RecoveryMode)) {
|
||||
if ($rpinfo.State -eq 'Protecting') {
|
||||
throw "This recovery plan action needs to be initiated from the other SRM instance"
|
||||
}
|
||||
|
||||
$RecoveryPlan.Start($RecoveryMode, $rpOpt)
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Stop a running Recovery Plan action.
|
||||
|
||||
.PARAMETER RecoveryPlan
|
||||
The recovery plan to stop
|
||||
#>
|
||||
Function Stop-RecoveryPlan {
|
||||
[cmdletbinding(SupportsShouldProcess=$True,ConfirmImpact="High")]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true, Position=1)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan
|
||||
)
|
||||
|
||||
# Validate with informative error messages
|
||||
$rpinfo = $RecoveryPlan.GetInfo()
|
||||
|
||||
# Prompt the user to confirm they want to cancel the running action
|
||||
if ($pscmdlet.ShouldProcess($rpinfo.Name, 'Cancel')) {
|
||||
|
||||
$RecoveryPlan.Cancel()
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Retrieve the historical results of a recovery plan
|
||||
|
||||
.PARAMETER RecoveryPlan
|
||||
The recovery plan to retrieve the history for
|
||||
#>
|
||||
Function Get-RecoveryPlanResult {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true, Position=1)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
|
||||
[VMware.VimAutomation.Srm.Views.SrmRecoveryPlanRecoveryMode] $RecoveryMode,
|
||||
[VMware.VimAutomation.Srm.Views.SrmRecoveryResultResultState] $ResultState,
|
||||
[DateTime] $StartedAfter,
|
||||
[DateTime] $startedBefore,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
|
||||
|
||||
# Get the history objects
|
||||
$history = $api.Recovery.GetHistory($RecoveryPlan.MoRef)
|
||||
$resultCount = $history.GetResultCount()
|
||||
|
||||
if ($resultCount -gt 0) {
|
||||
$results = $history.GetRecoveryResult($resultCount)
|
||||
|
||||
$results |
|
||||
Where-Object { -not $RecoveryMode -or $_.RunMode -eq $RecoveryMode } |
|
||||
Where-Object { -not $ResultState -or $_.ResultState -eq $ResultState } |
|
||||
Where-Object { $null -eq $StartedAfter -or $_.StartTime -gt $StartedAfter } |
|
||||
Where-Object { $null -eq $StartedBefore -or $_.StartTime -lt $StartedBefore }
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Exports a recovery plan result object to XML format
|
||||
|
||||
.PARAMETER RecoveryPlanResult
|
||||
The recovery plan result to export
|
||||
#>
|
||||
Function Export-RecoveryPlanResultAsXml {
|
||||
[cmdletbinding()]
|
||||
[OutputType([xml])]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true, Position=1)][VMware.VimAutomation.Srm.Views.SrmRecoveryResult] $RecoveryPlanResult,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
|
||||
|
||||
$RecoveryPlan = $RecoveryPlanResult.Plan
|
||||
$history = $api.Recovery.GetHistory($RecoveryPlan.MoRef)
|
||||
$lines = $history.GetResultLength($RecoveryPlanResult.Key)
|
||||
[xml] $history.RetrieveStatus($RecoveryPlanResult.Key, 0, $lines)
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Add a protection group to a recovery plan. This requires SRM 5.8 or later.
|
||||
|
||||
.PARAMETER RecoveryPlan
|
||||
The recovery plan the protection group will be associated with
|
||||
|
||||
.PARAMETER ProtectionGroup
|
||||
The protection group to associate with the recovery plan
|
||||
#>
|
||||
Function Add-ProtectionGroupToRecoveryPlan {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true, Position=1)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true, Position=2)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup] $ProtectionGroup
|
||||
)
|
||||
|
||||
if ($RecoveryPlan -and $ProtectionGroup) {
|
||||
foreach ($pg in $ProtectionGroup) {
|
||||
try {
|
||||
$RecoveryPlan.AddProtectionGroup($pg.MoRef)
|
||||
} catch {
|
||||
Write-Error $_
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Remove a protection group to a recovery plan. This requires SRM 6.5 or later.
|
||||
|
||||
.PARAMETER RecoveryPlan
|
||||
The recovery plan the protection group will be disassociated from
|
||||
|
||||
.PARAMETER ProtectionGroup
|
||||
The protection group to disassociate from the recovery plan
|
||||
#>
|
||||
Function Remove-ProtectionGroupFromRecoveryPlan {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup] $ProtectionGroup
|
||||
)
|
||||
|
||||
if ($RecoveryPlan -and $ProtectionGroup) {
|
||||
foreach ($pg in $ProtectionGroup) {
|
||||
try {
|
||||
$RecoveryPlan.RemoveProtectionGroupFromRecoveryPlan($pg.MoRef)
|
||||
} catch {
|
||||
Write-Error $_
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the recovery settings of a protected VM. This requires SRM 5.8 or later.
|
||||
|
||||
.PARAMETER RecoveryPlan
|
||||
The recovery plan the settings will be retrieved from.
|
||||
|
||||
.PARAMETER Vm
|
||||
The virtual machine to retieve recovery settings for.
|
||||
|
||||
#>
|
||||
Function Get-RecoverySetting {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $Vm,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.Vim.VirtualMachine] $VmView,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectedVm] $ProtectedVm
|
||||
)
|
||||
|
||||
$moRef = Get_MoRefFromVmObj -Vm $Vm -VmView $VmView -ProtectedVm $ProtectedVm
|
||||
|
||||
if ($RecoveryPlan -and $moRef) {
|
||||
$RecoveryPlan.GetRecoverySettings($moRef)
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the recovery settings of a protected VM. This requires SRM 5.8 or later.
|
||||
|
||||
.PARAMETER RecoveryPlan
|
||||
The recovery plan the settings will be retrieved from.
|
||||
|
||||
.PARAMETER Vm
|
||||
The virtual machine to configure recovery settings on.
|
||||
|
||||
.PARAMETER RecoverySettings
|
||||
The recovery settings to configure. These should have been retrieved via a
|
||||
call to Get-RecoverySettings
|
||||
|
||||
#>
|
||||
Function Set-RecoverySetting {
|
||||
[cmdletbinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $Vm,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.Vim.VirtualMachine] $VmView,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectedVm] $ProtectedVm,
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings
|
||||
)
|
||||
|
||||
|
||||
$moRef = Get_MoRefFromVmObj -Vm $Vm -VmView $VmView -ProtectedVm $ProtectedVm
|
||||
|
||||
if ($RecoveryPlan -and $moRef -and $RecoverySettings) {
|
||||
if ($PSCmdlet.ShouldProcess("$moRef", "Set")) {
|
||||
$RecoveryPlan.SetRecoverySettings($moRef, $RecoverySettings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a new per-Vm command to add to the SRM Recovery Plan
|
||||
|
||||
.PARAMETER Command
|
||||
The command script to execute.
|
||||
|
||||
.PARAMETER Description
|
||||
The user friendly description of this script.
|
||||
|
||||
.PARAMETER Timeout
|
||||
The number of seconds this command has to execute before it will be timedout.
|
||||
|
||||
.PARAMETER RunInRecoveredVm
|
||||
For a post-power on command this flag determines whether it will run on the
|
||||
recovered VM or on the SRM server.
|
||||
|
||||
#>
|
||||
Function New-Command {
|
||||
[cmdletbinding(SupportsShouldProcess=$true, ConfirmImpact="None")]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true)][string] $Command,
|
||||
[Parameter (Mandatory=$true)][string] $Description,
|
||||
[int] $Timeout = 300,
|
||||
[switch] $RunInRecoveredVm = $false
|
||||
)
|
||||
|
||||
if($PSCmdlet.ShouldProcess("Description", "New")) {
|
||||
$srmWsdlCmd = New-Object VMware.VimAutomation.Srm.WsdlTypes.SrmCommand
|
||||
$srmCmd = New-Object VMware.VimAutomation.Srm.Views.SrmCommand -ArgumentList $srmWsdlCmd
|
||||
$srmCmd.Command = $Command
|
||||
$srmCmd.Description = $Description
|
||||
$srmCmd.RunInRecoveredVm = $RunInRecoveredVm
|
||||
$srmCmd.Timeout = $Timeout
|
||||
$srmCmd.Uuid = [guid]::NewGuid()
|
||||
|
||||
return $srmCmd
|
||||
}
|
||||
}
|
||||
|
||||
<# Internal function #>
|
||||
Function Add_Command {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings,
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmCommand] $SrmCommand,
|
||||
[Parameter (Mandatory=$true)][bool] $PostRecovery
|
||||
)
|
||||
|
||||
if ($PostRecovery) {
|
||||
$commands = $RecoverySettings.PostPowerOnCallouts
|
||||
} else {
|
||||
$commands = $RecoverySettings.PrePowerOnCallouts
|
||||
}
|
||||
|
||||
if (-not $commands) {
|
||||
$commands = New-Object System.Collections.Generic.List[VMware.VimAutomation.Srm.Views.SrmCallout]
|
||||
}
|
||||
$commands.Add($SrmCommand)
|
||||
|
||||
if ($PostRecovery) {
|
||||
$RecoverySettings.PostPowerOnCallouts = $commands
|
||||
} else {
|
||||
$RecoverySettings.PrePowerOnCallouts = $commands
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Add an SRM command to the set of pre recovery callouts for a VM.
|
||||
|
||||
.PARAMETER RecoverySettings
|
||||
The recovery settings to update. These should have been retrieved via a
|
||||
call to Get-RecoverySettings
|
||||
|
||||
.PARAMETER SrmCommand
|
||||
The command to add to the list.
|
||||
|
||||
#>
|
||||
Function Add-PreRecoveryCommand {
|
||||
[cmdletbinding()]
|
||||
[OutputType([VMware.VimAutomation.Srm.Views.SrmRecoverySettings])]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings,
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmCommand] $SrmCommand
|
||||
)
|
||||
Add_Command -RecoverySettings $RecoverySettings -SrmCommand $SrmCommand -PostRecovery $false
|
||||
return $RecoverySettings
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Remove an SRM command from the set of pre recovery callouts for a VM.
|
||||
|
||||
.PARAMETER RecoverySettings
|
||||
The recovery settings to update. These should have been retrieved via a
|
||||
call to Get-RecoverySettings
|
||||
|
||||
.PARAMETER SrmCommand
|
||||
The command to remove from the list.
|
||||
|
||||
#>
|
||||
Function Remove-PreRecoveryCommand {
|
||||
[cmdletbinding(SupportsShouldProcess=$true, ConfirmImpact="Low")]
|
||||
[OutputType([VMware.VimAutomation.Srm.Views.SrmRecoverySettings])]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings,
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmCommand] $SrmCommand
|
||||
)
|
||||
|
||||
if ($pscmdlet.ShouldProcess($SrmCommand.Description, "Remove")) {
|
||||
$RecoverySettings.PrePowerOnCallouts.Remove($SrmCommand)
|
||||
}
|
||||
|
||||
return $RecoverySettings
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Add an SRM command to the set of post recovery callouts for a VM.
|
||||
|
||||
.PARAMETER RecoverySettings
|
||||
The recovery settings to update. These should have been retrieved via a
|
||||
call to Get-RecoverySettings
|
||||
|
||||
.PARAMETER SrmCommand
|
||||
The command to add to the list.
|
||||
|
||||
#>
|
||||
Function Add-PostRecoveryCommand {
|
||||
[cmdletbinding()]
|
||||
[OutputType([VMware.VimAutomation.Srm.Views.SrmRecoverySettings])]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings,
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmCommand] $SrmCommand
|
||||
)
|
||||
|
||||
Add_Command -RecoverySettings $RecoverySettings -SrmCommand $SrmCommand -PostRecovery $true
|
||||
|
||||
return $RecoverySettings
|
||||
}
|
||||
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Remove an SRM command from the set of post recovery callouts for a VM.
|
||||
|
||||
.PARAMETER RecoverySettings
|
||||
The recovery settings to update. These should have been retrieved via a
|
||||
call to Get-RecoverySettings
|
||||
|
||||
.PARAMETER SrmCommand
|
||||
The command to remove from the list.
|
||||
|
||||
#>
|
||||
Function Remove-PostRecoveryCommand {
|
||||
[cmdletbinding(SupportsShouldProcess=$true, ConfirmImpact="Low")]
|
||||
[OutputType([VMware.VimAutomation.Srm.Views.SrmRecoverySettings])]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings,
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmCommand] $SrmCommand
|
||||
)
|
||||
|
||||
if ($pscmdlet.ShouldProcess($SrmCommand.Description, "Remove")) {
|
||||
$RecoverySettings.PostPowerOnCallouts.Remove($SrmCommand)
|
||||
}
|
||||
|
||||
return $RecoverySettings
|
||||
}
|
||||
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a new recovery plan
|
||||
|
||||
.PARAMETER Name
|
||||
The name for this recovery plan
|
||||
|
||||
.PARAMETER Description
|
||||
A description of the recovery plan
|
||||
|
||||
.PARAMETER Folder
|
||||
The recovery plan folder in which to create this recovery plan. Will default to
|
||||
the root recovery plan folder
|
||||
|
||||
.PARAMETER ProtectionGroups
|
||||
The protection groups to associate with this recovery plan
|
||||
|
||||
.PARAMETER TestNetworkMappings
|
||||
The test network mappings to configure as part of this recovery plan
|
||||
|
||||
.PARAMETER SrmServer
|
||||
The SRM Server to operate against
|
||||
#>
|
||||
Function New-RecoveryPlan {
|
||||
[cmdletbinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true)][string] $Name,
|
||||
[string] $Description,
|
||||
[VMware.VimAutomation.Srm.Views.SrmRecoveryPlanFolder] $Folder,
|
||||
[VMware.VimAutomation.Srm.Views.SrmProtectionGroup[]] $ProtectionGroups,
|
||||
[VMware.VimAutomation.Srm.Views.SrmRecoveryTestNetworkMapping[]] $TestNetworkMappings,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
|
||||
|
||||
if (-not $Folder) {
|
||||
$Folder = Get-RecoveryPlanFolder -SrmServer $SrmServer
|
||||
}
|
||||
|
||||
$protectionGroupmRefs += @( $ProtectionGroups | ForEach-Object { $_.MoRef } | Select-Object -Unique)
|
||||
|
||||
[VMware.VimAutomation.Srm.Views.CreateRecoveryPlanTask] $task = $null
|
||||
|
||||
if ($PSCmdlet.ShouldProcess($Name, "New")) {
|
||||
$task = $api.Recovery.CreateRecoveryPlan(
|
||||
$Name,
|
||||
$Folder.MoRef,
|
||||
$protectionGroupmRefs,
|
||||
$Description,
|
||||
$TestNetworkMappings
|
||||
)
|
||||
}
|
||||
|
||||
while(-not $task.IsCreateRecoveryPlanComplete()) { Start-Sleep -Seconds 1 }
|
||||
|
||||
$task.GetNewRecoveryPlan()
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Remove a recovery plan permanently
|
||||
|
||||
.PARAMETER RecoveryPlan
|
||||
The recovery plan to remove
|
||||
|
||||
.PARAMETER SrmServer
|
||||
The SRM Server to operate against
|
||||
#>
|
||||
Function Remove-RecoveryPlan {
|
||||
[cmdletbinding(SupportsShouldProcess=$True, ConfirmImpact="High")]
|
||||
Param(
|
||||
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
|
||||
|
||||
$rpinfo = $RecoveryPlan.GetInfo()
|
||||
if ($pscmdlet.ShouldProcess($rpinfo.Name, "Remove")) {
|
||||
$api.Recovery.DeleteRecoveryPlan($RecoveryPlan.MoRef)
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get a recovery plan folder
|
||||
|
||||
.PARAMETER SrmServer
|
||||
The SRM Server to query for the recovery plan folder
|
||||
#>
|
||||
Function Get-RecoveryPlanFolder {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
|
||||
|
||||
$folder = $api.Recovery.GetRecoveryPlanRootFolder()
|
||||
|
||||
return $folder
|
||||
}
|
||||
33
Modules/SRM/Meadowcroft.Srm.Storage.ps1
Normal file
33
Modules/SRM/Meadowcroft.Srm.Storage.ps1
Normal file
@@ -0,0 +1,33 @@
|
||||
<#
|
||||
Copyright 2017-2021 VMware, Inc.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
#>
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
|
||||
# SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Trigger Discover Devices for Site Recovery Manager
|
||||
|
||||
.OUTPUTS
|
||||
Returns discover devices task
|
||||
#>
|
||||
Function Start-DiscoverDevice {
|
||||
[cmdletbinding(SupportsShouldProcess=$True, ConfirmImpact="Medium")]
|
||||
[OutputType([VMware.VimAutomation.Srm.Views.DiscoverDevicesTask])]
|
||||
Param(
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
|
||||
$name = $SrmServer.Name
|
||||
[VMware.VimAutomation.Srm.Views.DiscoverDevicesTask] $task = $null
|
||||
if ($pscmdlet.ShouldProcess($name, "Rescan Storage Devices")) {
|
||||
$task = $api.Storage.DiscoverDevices()
|
||||
}
|
||||
return $task
|
||||
}
|
||||
101
Modules/SRM/Meadowcroft.Srm.psd1
Normal file
101
Modules/SRM/Meadowcroft.Srm.psd1
Normal file
@@ -0,0 +1,101 @@
|
||||
<#
|
||||
Copyright 2017-2021 VMware, Inc.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
#>
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
|
||||
#
|
||||
# Module manifest for module 'Meadowcroft.Srm'
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'Meadowcroft.Srm.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '0.2'
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = 'f9247009-9168-4a21-831b-819f82884ffe'
|
||||
|
||||
# Author of this module
|
||||
Author = 'Ben Meadowcroft'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'VMware, Inc'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = '(c) 2014 - 2017. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
# Description = ''
|
||||
|
||||
# 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 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 = @{ModuleName='VMware.VimAutomation.Srm'; ModuleVersion='6.5'}
|
||||
|
||||
# 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 = 'Meadowcroft.Srm.Recovery.ps1','Meadowcroft.Srm.Protection.ps1','Meadowcroft.Srm.Storage.ps1'
|
||||
# NestedModules = @()
|
||||
|
||||
# Functions to export from this module, note that internal functions use '_' not '-' as separator
|
||||
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 = 'Srm'
|
||||
|
||||
}
|
||||
156
Modules/SRM/Meadowcroft.Srm.psm1
Normal file
156
Modules/SRM/Meadowcroft.Srm.psm1
Normal file
@@ -0,0 +1,156 @@
|
||||
<#
|
||||
Copyright 2017-2021 VMware, Inc.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
#>
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
# SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This is intended to be an "internal" function only. It filters a
|
||||
pipelined input of objects and elimiates duplicates as identified
|
||||
by the MoRef property on the object.
|
||||
|
||||
.LINK
|
||||
https://github.com/benmeadowcroft/SRM-Cmdlets/
|
||||
#>
|
||||
Function Select_UniqueByMoRef {
|
||||
|
||||
Param(
|
||||
[Parameter (ValueFromPipeline=$true)] $in
|
||||
)
|
||||
process {
|
||||
$moref = New-Object System.Collections.ArrayList
|
||||
$in | Sort-Object | Select-Object MoRef -Unique | ForEach-Object { $moref.Add($_.MoRef) } > $null
|
||||
$in | ForEach-Object {
|
||||
if ($_.MoRef -in $moref) {
|
||||
$moref.Remove($_.MoRef)
|
||||
$_ #output
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This is intended to be an "internal" function only. It gets the
|
||||
MoRef property of a VM from either a VM object, a VM view, or the
|
||||
protected VM object.
|
||||
#>
|
||||
Function Get_MoRefFromVmObj {
|
||||
Param(
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $Vm,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.Vim.VirtualMachine] $VmView,
|
||||
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectedVm] $ProtectedVm
|
||||
)
|
||||
|
||||
|
||||
$moRef = $null
|
||||
if ($Vm.ExtensionData.MoRef) { # VM object
|
||||
$moRef = $Vm.ExtensionData.MoRef
|
||||
} elseif ($VmView.MoRef) { # VM view
|
||||
$moRef = $VmView.MoRef
|
||||
} elseif ($protectedVm) {
|
||||
$moRef = $ProtectedVm.Vm.MoRef
|
||||
}
|
||||
|
||||
$moRef
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Lookup the srm instance for a specific server.
|
||||
#>
|
||||
Function Get-Server {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[string] $SrmServerAddress,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
$found = $null
|
||||
|
||||
if ($SrmServer) {
|
||||
$found = $SrmServer
|
||||
} elseif ($SrmServerAddress) {
|
||||
# search for server address in default servers
|
||||
$global:DefaultSrmServers | ForEach-Object {
|
||||
if ($_.Name -ieq $SrmServerAddress) {
|
||||
$found = $_
|
||||
}
|
||||
}
|
||||
if (-not $found) {
|
||||
throw "SRM server $SrmServerAddress not found. Connect-Server must be called first."
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $found) {
|
||||
#default result
|
||||
$found = $global:DefaultSrmServers[0]
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Retrieve the SRM Server Version
|
||||
#>
|
||||
Function Get-ServerVersion {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
$srm = Get-Server $SrmServer
|
||||
$srm.Version
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Lookup the SRM API endpoint for a specific server.
|
||||
#>
|
||||
Function Get-ServerApiEndpoint {
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
[string] $SrmServerAddress,
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
|
||||
)
|
||||
|
||||
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $server = Get-Server -SrmServerAddress $SrmServerAddress -SrmServer $SrmServer
|
||||
|
||||
return $server.ExtensionData
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the placeholder VMs that are associated with SRM
|
||||
#>
|
||||
Function Get-PlaceholderVM {
|
||||
[cmdletbinding()]
|
||||
Param()
|
||||
Get-VM @Args | Where-Object {$_.ExtensionData.Config.ManagedBy.extensionKey -like "com.vmware.vcDr*" -and $_.ExtensionData.Config.ManagedBy.Type -ieq 'placeholderVm'}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the test VMs that are associated with SRM
|
||||
#>
|
||||
Function Get-TestVM {
|
||||
[cmdletbinding()]
|
||||
Param()
|
||||
Get-VM @Args | Where-Object {$_.ExtensionData.Config.ManagedBy.extensionKey -like "com.vmware.vcDr*" -and $_.ExtensionData.Config.ManagedBy.Type -ieq 'testVm'}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the VMs that are replicated using vSphere Replication. These may not be SRM
|
||||
protected VMs.
|
||||
#>
|
||||
Function Get-ReplicatedVM {
|
||||
[cmdletbinding()]
|
||||
Param()
|
||||
Get-VM @Args | Where-Object {($_.ExtensionData.Config.ExtraConfig | Where-Object { $_.Key -eq 'hbr_filter.destination' -and $_.Value } )}
|
||||
}
|
||||
10
Modules/SRM/NOTICE.txt
Normal file
10
Modules/SRM/NOTICE.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
Copyright (c) 2017-2021 VMware, Inc. All Rights Reserved.
|
||||
|
||||
This product is licensed to you under the Apache License version 2.0 (the "License"). You may not use this product except in compliance with the License.
|
||||
|
||||
This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||
|
||||
Copyright (c) 2021 VMware, Inc. All Rights Reserved.
|
||||
|
||||
This product is licensed to you under the BSD-2-Clause License. You may not use this product except in compliance with the License.
|
||||
81
Modules/SRM/README.md
Normal file
81
Modules/SRM/README.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# SRM PowerCLI Cmdlets
|
||||
|
||||
Helper functions for working with VMware SRM 6.5 with PowerCLI 6.5.1 or later. PowerShell 5.0 and above is required.
|
||||
|
||||
This module is provided for illustrative/educational purposes to explain how the PowerCLI access to the SRM public API can be used.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Getting the SRM cmdlets
|
||||
|
||||
The latest version of the software can be cloned from the git repository:
|
||||
|
||||
git clone https://github.com/benmeadowcroft/SRM-Cmdlets.git
|
||||
|
||||
Or downloaded as a [zip file](https://github.com/benmeadowcroft/SRM-Cmdlets/archive/master.zip).
|
||||
|
||||
Specific releases (compatible with earlier PowerCLI and SRM versions) can be downloaded via the [release page](https://github.com/benmeadowcroft/SRM-Cmdlets/releases).
|
||||
|
||||
### Deploy SRM-Cmdlets module
|
||||
|
||||
After cloning (or downloading and extracting) the PowerShell module, you can import the module into your current PowerShell session by by passing the path to `Meadowcroft.Srm.psd1` to the `Import-Module` cmdlet, e.g.:
|
||||
|
||||
Import-Module -Name .\SRM-Cmdlets\Meadowcroft.Srm.psd1
|
||||
|
||||
You can also install the module into the PowerShell path so it can be loaded implicitly. See [Microsoft's Installing Modules instructions](http://msdn.microsoft.com/en-us/library/dd878350) for more details on how to do this.
|
||||
|
||||
The module uses the default prefix of `Srm` for the custom functions it defines. This can be overridden when importing the module by setting the value of the `-Prefix` parameter when calling `Import-Module`.
|
||||
|
||||
### Connecting to SRM
|
||||
|
||||
After installing the module the next step is to connect to the SRM server. Details of how to do this are located in the [PowerCLI 6.5.1 User's Guide](http://pubs.vmware.com/vsphere-65/topic/com.vmware.powercli.ug.doc/GUID-A5F206CF-264D-4565-8CB9-4ED1C337053F.html)
|
||||
|
||||
$credential = Get-Credential
|
||||
Connect-VIServer -Server vc-a.example.com -Credential $credential
|
||||
Connect-SrmServer -Credential $credential -RemoteCredential $credential
|
||||
|
||||
At this point we've just been using the cmdlets provided by PowerCLI, the PowerCLI documentation also provides some examples of how to call the SRM API to perform various tasks. In the rest of this introduction we'll perform some of those tasks using the custom functions defined in this project.
|
||||
|
||||
### Report the Protected Virtual Machines and Their Protection Groups
|
||||
|
||||
Goal: Create a simple report listing the VMs protected by SRM and the protection group they belong to.
|
||||
|
||||
Get-SrmProtectionGroup | %{
|
||||
$pg = $_
|
||||
Get-SrmProtectedVM -ProtectionGroup $pg } | %{
|
||||
$output = "" | select VmName, PgName
|
||||
$output.VmName = $_.Vm.Name
|
||||
$output.PgName = $pg.GetInfo().Name
|
||||
$output
|
||||
} | Format-Table @{Label="VM Name"; Expression={$_.VmName} },
|
||||
@{Label="Protection group name"; Expression={$_.PgName}
|
||||
}
|
||||
|
||||
### Report the Last Recovery Plan Test
|
||||
|
||||
Goal: Create a simple report listing the state of the last test of a recovery plan
|
||||
|
||||
Get-SrmRecoveryPlan | %{ $_ |
|
||||
Get-SrmRecoveryPlanResult -RecoveryMode Test | select -First 1
|
||||
} | Select Name, StartTime, RunMode, ResultState | Format-Table
|
||||
|
||||
|
||||
### Execute a Recovery Plan Test
|
||||
|
||||
Goal: for a specific recovery plan, execute a test failover. Note the "local" SRM server we are connected to should be the recovery site in order for this to be successful.
|
||||
|
||||
Get-SrmRecoveryPlan -Name "Name of Plan" | Start-SrmRecoveryPlan -RecoveryMode Test
|
||||
|
||||
### Export the Detailed XML Report of the Last Recovery Plan Workflow
|
||||
|
||||
Goal: get the XML report of the last recovery plan execution for a specific recovery plan.
|
||||
|
||||
Get-SrmRecoveryPlan -Name "Name of Plan" | Get-SrmRecoveryPlanResult |
|
||||
select -First 1 | Export-SrmRecoveryPlanResultAsXml
|
||||
|
||||
### Protect a Replicated VM
|
||||
|
||||
Goal: Take a VM replicated using vSphere Replication or Array Based Replication, add it to an appropriate protection group and configure it for protection
|
||||
|
||||
$pg = Get-SrmProtectionGroup "Name of Protection Group"
|
||||
Get-VM vm-01a | Protect-SrmVM -ProtectionGroup $pg
|
||||
41
Modules/SaltStackConfig/SaltStackConfig.Format.ps1xml
Normal file
41
Modules/SaltStackConfig/SaltStackConfig.Format.ps1xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Configuration>
|
||||
<ViewDefinitions>
|
||||
<View>
|
||||
<Name>SscConnection</Name>
|
||||
<ViewSelectedBy>
|
||||
<TypeName>SscConnection</TypeName>
|
||||
</ViewSelectedBy>
|
||||
<TableControl>
|
||||
<TableHeaders>
|
||||
<TableColumnHeader>
|
||||
<Width>30</Width>
|
||||
<Label>Name</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>30</Width>
|
||||
<Label>User</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Label>Authenticated</Label>
|
||||
</TableColumnHeader>
|
||||
</TableHeaders>
|
||||
<TableRowEntries>
|
||||
<TableRowEntry>
|
||||
<TableColumnItems>
|
||||
<TableColumnItem>
|
||||
<PropertyName>Name</PropertyName>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<PropertyName>User</PropertyName>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<PropertyName>Authenticated</PropertyName>
|
||||
</TableColumnItem>
|
||||
</TableColumnItems>
|
||||
</TableRowEntry>
|
||||
</TableRowEntries>
|
||||
</TableControl>
|
||||
</View>
|
||||
</ViewDefinitions>
|
||||
</Configuration>
|
||||
129
Modules/SaltStackConfig/SaltStackConfig.psd1
Normal file
129
Modules/SaltStackConfig/SaltStackConfig.psd1
Normal file
@@ -0,0 +1,129 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
|
||||
#
|
||||
# Module manifest for module 'SaltStackConfig'
|
||||
#
|
||||
# Generated by: Brian Wuchner
|
||||
#
|
||||
# Generated on: 11/28/2021
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'SaltStackConfig.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '0.0.8'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '9a36e984-2f63-450e-8c14-a6bccb18f87a'
|
||||
|
||||
# Author of this module
|
||||
Author = 'Brian Wuchner'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'VMware'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = '(c) VMware. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = 'Community sourced PowerShell wrapper module for the vRealize Automation SaltStack Config API.'
|
||||
|
||||
# Minimum version of the Windows PowerShell engine required by this module
|
||||
PowerShellVersion = '4.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. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# DotNetFrameworkVersion = ''
|
||||
|
||||
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# 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 = @('SaltStackConfig.Format.ps1xml')
|
||||
|
||||
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
||||
# NestedModules = @()
|
||||
|
||||
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
|
||||
FunctionsToExport = @('Connect-SscServer', 'Disconnect-SscServer', 'Get-SscActivity', 'Get-SscData', 'Get-SscJob', 'Get-SscMaster', 'Get-SscMinionCache', 'Get-SscReturn',
|
||||
'Get-SscSchedule','Get-SscFile','Set-SscFile','New-SscFile','Remove-SscFile','Get-SscLicense','Get-SscvRALicense','Get-SscMinionKey','Set-SscMinionKey',
|
||||
'Remove-SscMinionKey')
|
||||
|
||||
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
|
||||
CmdletsToExport = @()
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = '*'
|
||||
|
||||
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
|
||||
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 = ''
|
||||
|
||||
# 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 = ''
|
||||
|
||||
}
|
||||
640
Modules/SaltStackConfig/SaltStackConfig.psm1
Normal file
640
Modules/SaltStackConfig/SaltStackConfig.psm1
Normal file
@@ -0,0 +1,640 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
Function Connect-SscServer {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: November 27, 2021
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
Use this function to create the cookie/header to connect to SaltStack Config RaaS API
|
||||
.DESCRIPTION
|
||||
This function will allow you to connect to a vRealize Automation SaltStack Config RaaS API.
|
||||
A global variable will be set with the Servername & Cookie/Header value for use by other functions.
|
||||
.EXAMPLE
|
||||
PS C:\> Connect-SscServer -Server 'salt.example.com' -Username 'root' -Password 'VMware1!'
|
||||
This will default to internal user authentication.
|
||||
.EXAMPLE
|
||||
PS C:\> Connect-SscServer -Server 'salt.example.com' -Username 'bwuchner' -Password 'MyPassword1!' -AuthSource 'LAB Directory'
|
||||
This will use the 'Lab Directory' LDAP authentication source.
|
||||
.EXAMPLE
|
||||
PS C:\> Connect-SscServer -Server 'salt.example.com'
|
||||
This will prompt for credentials
|
||||
.EXAMPLE
|
||||
$creds = Get-Credential
|
||||
PS C:\> Connect-SscServer -Server 'salt.example.com' -Credential $creds -AuthSource 'LAB Directory'
|
||||
This will connect to the 'LAB Directory' LDAP authentication source using a specified credential.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true, Position=0)][string]$server,
|
||||
[Parameter(Mandatory=$true, ParameterSetName='PlainText', Position=1)][string]$username,
|
||||
[Parameter(Mandatory=$true, ParameterSetName='PlainText', Position=2)][ValidateNotNullOrEmpty()][string]$password,
|
||||
[Parameter(Mandatory=$false, Position=3)][string]$AuthSource='internal',
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Credential')][PSCredential]$Credential,
|
||||
[Parameter(Mandatory=$false)][Switch]$SkipCertificateCheck,
|
||||
[Parameter(Mandatory=$false)][System.Net.SecurityProtocolType]$SslProtocol
|
||||
)
|
||||
|
||||
if ($PSCmdlet.ParameterSetName -eq 'Credential' -AND $Credential -eq $null) { $Credential = Get-Credential}
|
||||
if ($Credential) {
|
||||
$username = $Credential.GetNetworkCredential().username
|
||||
$password = $Credential.GetNetworkCredential().password
|
||||
}
|
||||
|
||||
if ($SkipCertificateCheck) {
|
||||
# This if statement is using example code from https://stackoverflow.com/questions/11696944/powershell-v3-invoke-webrequest-https-error
|
||||
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
|
||||
} # end if SkipCertificate Check
|
||||
|
||||
if ($SslProtocol) {
|
||||
[System.Net.ServicePointManager]::SecurityProtocol = $SslProtocol
|
||||
}
|
||||
|
||||
$loginBody = @{'username'=$username; 'password'=$password; 'config_name'=$AuthSource}
|
||||
try {
|
||||
$webRequest = Invoke-WebRequest -Uri "https://$server/account/login" -SessionVariable ws
|
||||
$ws.headers.Add('X-Xsrftoken', $webRequest.headers.'x-xsrftoken')
|
||||
$webRequest = Invoke-WebRequest -Uri "https://$server/account/login" -WebSession $ws -method POST -body (ConvertTo-Json $loginBody)
|
||||
$webRequestJson = ConvertFrom-JSON $webRequest.Content
|
||||
$global:DefaultSscConnection = New-Object psobject -property @{ 'SscWebSession'=$ws; 'Name'=$server; 'ConnectionDetail'=$webRequestJson;
|
||||
'User'=$webRequestJson.attributes.config_name +'\'+ $username; 'Authenticated'=$webRequestJson.authenticated; PSTypeName='SscConnection' }
|
||||
|
||||
# Return the connection object
|
||||
$global:DefaultSscConnection
|
||||
} catch {
|
||||
Write-Error ("Failure connecting to $server. " + $_)
|
||||
} # end try/catch block
|
||||
}
|
||||
|
||||
Function Disconnect-SscServer {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: November 27, 2021
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function clears a previously created cookie/header used to connect to SaltStack Config
|
||||
.DESCRIPTION
|
||||
This function will clear the global variable used to connect to the vRealize Automation SaltStack Config RaaS API
|
||||
.EXAMPLE
|
||||
PS C:\> Disconnect-SscServer
|
||||
#>
|
||||
if ($global:DefaultSscConnection) {
|
||||
$global:DefaultSscConnection = $null
|
||||
} else {
|
||||
Write-Error 'Could not find an existing connection.'
|
||||
} # end if
|
||||
}
|
||||
|
||||
Function Get-SscData {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: November 27, 2021
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
Use this function to call the SaltStack Config API.
|
||||
Additional helper functions will call this function, this is where the majority of the logic will happen.
|
||||
.DESCRIPTION
|
||||
This function will pass resource/method/arguments to the vRealize Automation SaltStack Config RaaS API.
|
||||
It depends on a global variable created by Connect-SscServer.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscData -Resource 'minions' -Method 'get_minion_cache'
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$resource,
|
||||
[Parameter(Mandatory=$true)][string]$method,
|
||||
[System.Collections.Hashtable]$kwarg
|
||||
)
|
||||
|
||||
if (!$global:DefaultSscConnection) {
|
||||
Write-Error 'You are not currently connected to any servers. Please connect first using Connect-SscServer.'
|
||||
return;
|
||||
} # end if
|
||||
|
||||
if (!$kwarg) {
|
||||
$body = @{'resource'=$resource; 'method'=$method }
|
||||
} else {
|
||||
$body = @{'resource'=$resource; 'method'=$method; 'kwarg'=$kwarg }
|
||||
}
|
||||
|
||||
try{
|
||||
$jsonBody = $(ConvertTo-Json $body -Depth 4 -Compress )
|
||||
write-debug "JSON Body: $jsonBody"
|
||||
$output = Invoke-WebRequest -WebSession $global:DefaultSscConnection.SscWebSession -Method POST -Uri "https://$($global:DefaultSscConnection.Name)/rpc" -body $jsonBody -ContentType 'application/json'
|
||||
$outputJson = (ConvertFrom-Json $output.Content)
|
||||
|
||||
if ($outputJson.error) { Write-Error $outputJson.error }
|
||||
if ($outputJson.warnings) { Write-Warning $outputJson.warnings }
|
||||
return $outputJson.ret
|
||||
|
||||
} catch {
|
||||
Write-Error $_.Exception.Message
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Lets include a couple sample/helper functions wrappers
|
||||
Function Get-SscMaster {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: November 27, 2021
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will return grain details about the SaltStack Config master node.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData master.get_master_grains.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscMaster
|
||||
#>
|
||||
|
||||
(Get-SscData master get_master_grains).salt.grains
|
||||
}
|
||||
|
||||
Function Get-SscMinionCache {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: November 27, 2021
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will return the grain property cache of SaltStack Config minions.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData minions.get_minion_cache.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscMinion
|
||||
#>
|
||||
|
||||
(Get-SscData minions get_minion_cache).results
|
||||
}
|
||||
|
||||
Function Get-SscJob {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: November 27, 2021
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will return configured SatlStack Config jobs.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData job.get_jobs.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscJob
|
||||
#>
|
||||
|
||||
(Get-SscData job get_jobs).results
|
||||
}
|
||||
|
||||
Function Get-SscSchedule {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: November 27, 2021
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will return schedules for SaltStack Config.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData schedule.get.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscSchedule
|
||||
#>
|
||||
|
||||
(Get-SscData schedule get).results
|
||||
}
|
||||
|
||||
Function Get-SscReturn {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: November 27, 2021
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will return job results from the job cache based on the provided arguments.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData ret.get_returns with either Jid or MinionID.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscReturn
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscReturn -Jid '20211122160147314949'
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscReturn -MinionID 't147-win22-01.lab.enterpriseadmins.org'
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscReturn -MinionID 't147-win22-01.lab.enterpriseadmins.org' -Jid '20211122160147314949'
|
||||
#>
|
||||
param(
|
||||
[string]$jid,
|
||||
[string]$MinionID
|
||||
)
|
||||
|
||||
$kwarg = @{}
|
||||
if ($jid) { $kwarg += @{'jid'=$jid} }
|
||||
if ($MinionID) { $kwarg += @{'minion_id'=$MinionID} }
|
||||
|
||||
(Get-SscData ret get_returns $kwarg).results
|
||||
}
|
||||
|
||||
Function Get-SscActivity {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: November 27, 2021
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will return SaltStack Config commands that have been issued.
|
||||
In the web interface this is similar to the Activity button.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData cmd.get_cmds.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscActivity
|
||||
#>
|
||||
|
||||
(Get-SscData cmd get_cmds).results
|
||||
}
|
||||
|
||||
Function Get-SscFile {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: February 12, 2022
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will return file contents from the file server based on the provided arguments.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData fs get_file and pass in specified saltenv and path parameters.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscFile -saltenv 'sse' -path '/myfiles/file.sls'
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscFile -fileuuid '5e2483e8-a981-4e8c-9e83-01d1930413db'
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true, ParameterSetName='ByFileUUID', ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][Alias('fileuuid')][string]$uuid,
|
||||
[Parameter(Mandatory=$true, ParameterSetName='ByFilePath')][string]$saltenv,
|
||||
[Parameter(Mandatory=$true, ParameterSetName='ByFilePath')][string]$path
|
||||
)
|
||||
|
||||
$kwarg = @{}
|
||||
if ($uuid) { $kwarg += @{'file_uuid'=$uuid } }
|
||||
if ($saltenv) {
|
||||
$kwarg += @{'saltenv'=$saltenv}
|
||||
$kwarg += @{'path'=$path}
|
||||
}
|
||||
|
||||
if ( Get-SscData fs file_exists $kwarg ) {
|
||||
Get-SscData fs get_file $kwarg
|
||||
} else {
|
||||
if ($uuid) { Write-Error "File with UUID: $uuid not found." } else { Write-Error "File at path $saltenv $path not found." }
|
||||
}
|
||||
}
|
||||
|
||||
Function Set-SscFile {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: February 12, 2022
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will update file contents on the file server based on the provided arguments.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData fs update_file and pass in specified fileuuid or saltenv and path parameters.
|
||||
.EXAMPLE
|
||||
PS C:\> Set-SscFile -saltenv 'sse' -path '/myfiles/file.sls' "#This is my content. `n#And so is this"
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscFile -saltenv 'sse' -path '/myfiles/file.sls' | Set-SscFile -contenttype 'text/x-yaml'
|
||||
#>
|
||||
[cmdletbinding(SupportsShouldProcess=$true,ConfirmImpact='High')]
|
||||
param(
|
||||
[Parameter(Mandatory=$true, ParameterSetName='ByFileUUID', ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][Alias('fileuuid')][string]$uuid,
|
||||
[Parameter(Mandatory=$true, ParameterSetName='ByFilePath')][string]$saltenv,
|
||||
[Parameter(Mandatory=$true, ParameterSetName='ByFilePath')][string]$path,
|
||||
[string]$content,
|
||||
[ValidateSet('text/plain','text/x-python','application/json','text/x-yaml')][string]$contenttype
|
||||
)
|
||||
|
||||
$kwarg = @{}
|
||||
if ($uuid) { $kwarg += @{'file_uuid'=$uuid } }
|
||||
if ($saltenv) {
|
||||
$kwarg += @{'saltenv'=$saltenv}
|
||||
$kwarg += @{'path'=$path}
|
||||
}
|
||||
|
||||
# if the file exists, get its contents based on the correct parameterset. If it does not exist recommend the correct function.
|
||||
if ( Get-SscData fs file_exists $kwarg ) {
|
||||
if ( $PSCmdlet.ParameterSetName -eq 'ByFileUUID' ) {
|
||||
$currentFile = Get-SscFile -fileuuid $uuid
|
||||
} else {
|
||||
$currentFile = Get-SscFile -saltenv $saltenv -path $path
|
||||
}
|
||||
} else {
|
||||
Write-Error "Specified file does not exist, use New-SscFile instead."
|
||||
return $null
|
||||
}
|
||||
|
||||
if (!$content) { $content = $currentFile.contents }
|
||||
$kwarg += @{'contents'=$content}
|
||||
|
||||
if (!$contenttype) { $contenttype = $currentfile.content_type }
|
||||
$kwarg += @{'content_type'=$contenttype}
|
||||
|
||||
if ($PSCmdlet.ShouldProcess( "$($currentFile.saltenv)$($currentFile.path) ($($currentFile.uuid))" , 'update')) {
|
||||
Get-SscData fs update_file $kwarg
|
||||
}
|
||||
}
|
||||
|
||||
Function New-SscFile {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: February 12, 2022
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will create a new file on the file server based on the provided arguments.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData fs save_file and pass in specified saltenv and path parameters.
|
||||
.EXAMPLE
|
||||
PS C:\> New-SscFile -saltenv 'sse' -path '/myfiles/file.sls' -content '#this is my file content' -contenttype 'text/plain'
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$saltenv,
|
||||
[Parameter(Mandatory=$true)][string]$path,
|
||||
[string]$content,
|
||||
[ValidateSet('text/plain','text/x-python','application/json','text/x-yaml')][string]$contenttype
|
||||
)
|
||||
|
||||
$kwarg = @{}
|
||||
$kwarg += @{'saltenv'=$saltenv}
|
||||
$kwarg += @{'path'=$path}
|
||||
|
||||
# if the file exists, get its contents based on the correct parameterset. If it does not exist recommend the correct function.
|
||||
if ( Get-SscData fs file_exists $kwarg ) {
|
||||
Write-Error "Specified file already exists, use Set-SscFile instead."
|
||||
return $null
|
||||
}
|
||||
|
||||
if ($content) { $kwarg += @{'contents'=$content} }
|
||||
|
||||
if ($contenttype) {
|
||||
# if a contenttype is passed to the function we'll use it
|
||||
$kwarg += @{'content_type'=$contenttype}
|
||||
} else {
|
||||
# and finally we'll default to text
|
||||
$kwarg += @{'content_type' = 'text/plain' }
|
||||
}
|
||||
|
||||
Get-SscData fs save_file $kwarg
|
||||
}
|
||||
|
||||
Function Remove-SscFile {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: February 12, 2022
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will delete a specified file from the file server based on the provided arguments.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData fs delete_file and pass in specified fileuuid or saltenv and path parameters.
|
||||
.EXAMPLE
|
||||
PS C:\> Remove-SscFile -saltenv 'sse' -path '/myfiles/file.sls'
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscFile -saltenv 'sse' -path '/myfiles/file.sls' | Remove-SscFile
|
||||
#>
|
||||
[cmdletbinding(SupportsShouldProcess=$true,ConfirmImpact='High')]
|
||||
param(
|
||||
[Parameter(Mandatory=$true, ParameterSetName='ByFileUUID', ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][Alias('fileuuid')][string]$uuid,
|
||||
[Parameter(Mandatory=$true, ParameterSetName='ByFilePath')][string]$saltenv,
|
||||
[Parameter(Mandatory=$true, ParameterSetName='ByFilePath')][string]$path
|
||||
)
|
||||
|
||||
$kwarg = @{}
|
||||
if ($uuid) { $kwarg += @{'file_uuid'=$uuid } }
|
||||
if ($saltenv) {
|
||||
$kwarg += @{'saltenv'=$saltenv}
|
||||
$kwarg += @{'path'=$path}
|
||||
}
|
||||
|
||||
if ( Get-SscData fs file_exists $kwarg ) {
|
||||
if ($PSCmdlet.ShouldProcess( $(if ($uuid) {$uuid} else {"$saltenv $path"}) , 'delete')) {
|
||||
Get-SscData fs delete_file $kwarg
|
||||
}
|
||||
} else {
|
||||
Write-Error "Specified file does not exist."
|
||||
return $null
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-SscLicense {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: February 12, 2022
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will return license information for SaltStack Config.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData license.get_current_license and return the desc property.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscLicense
|
||||
#>
|
||||
|
||||
(Get-SscData license get_current_license).desc
|
||||
}
|
||||
|
||||
Function Get-SscvRALicense {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: February 12, 2022
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will return vRealize Automation license information for SaltStack Config.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData license.get_vra_license and return the serial and edition property.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscvRALicense
|
||||
#>
|
||||
|
||||
Get-SscData license get_vra_license
|
||||
}
|
||||
|
||||
Function Get-SscMinionKey {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: February 12, 2022
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will return minion key state information for SaltStack Config.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData minions.get_minion_key_state and return the minions key states.
|
||||
Optionally a key state can be provided and the results will be filtered to only return the requested state.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscMinionKeyState
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscMinionKeyState -key_state pending
|
||||
#>
|
||||
param(
|
||||
[ValidateSet('accepted','rejected','pending','denied')][string]$state
|
||||
)
|
||||
|
||||
$kwarg = @{}
|
||||
if ($state) { $kwarg.add('key_state',$state) }
|
||||
|
||||
(Get-SscData minions get_minion_key_state $kwarg).results
|
||||
}
|
||||
|
||||
|
||||
Function Set-SscMinionKey {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: February 12, 2022
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will set minion key state information for SaltStack Config.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData minions.set_minion_key_state and update the states for specific minions.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscMinionKeyState |?{$_.name -eq 'server2022a'} | Set-SscMinionKeyState -state accept
|
||||
.EXAMPLE
|
||||
PS C:\> Set-SscMinionKeyState -master 'salt' -minion 'server2022a' -state reject -confirm:$false
|
||||
#>
|
||||
[cmdletbinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][string]$master,
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][string]$minion,
|
||||
[Parameter(Mandatory, ParameterSetName='accept')][switch]$accept,
|
||||
[Parameter(Mandatory, ParameterSetName='reject')][switch]$reject
|
||||
)
|
||||
|
||||
begin {
|
||||
$collection = @()
|
||||
}
|
||||
|
||||
process {
|
||||
if ($PSCmdlet.ParameterSetName -eq 'accept') { $state = 'accept'}
|
||||
if ($PSCmdlet.ParameterSetName -eq 'reject') { $state = 'reject'}
|
||||
|
||||
if ($PSCmdlet.ShouldProcess("$master : $minion" , $state)) {
|
||||
$collection += ,@($master, $minion)
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
$kwarg = @{}
|
||||
$kwarg.Add('state', $state)
|
||||
if ($state -eq 'reject') {$kwarg.Add('include_accepted', $true)}
|
||||
if ($state -eq 'accept') {$kwarg.Add('include_rejected', $true)}
|
||||
if ($state -eq 'accept' -OR $state -eq 'reject') {$kwarg.Add('include_denied',$true)}
|
||||
$kwarg.Add('minions', @( $collection ) )
|
||||
|
||||
(Get-SscData minions set_minion_key_state $kwarg).task_ids
|
||||
}
|
||||
}
|
||||
|
||||
Function Remove-SscMinionKey {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Wuchner
|
||||
Date: February 12, 2022
|
||||
Blog: www.enterpriseadmins.org
|
||||
Twitter: @bwuch
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This wrapper function will delete a minion key for SaltStack Config.
|
||||
.DESCRIPTION
|
||||
This wrapper function will call Get-SscData minions.set_minion_key_state and remove the specified minion keys.
|
||||
.EXAMPLE
|
||||
PS C:\> Get-SscMinionKeyState |?{$_.name -eq 'server2022a'} | Remove-SscMinionKeyState
|
||||
.EXAMPLE
|
||||
PS C:\> Remove-SscMinionKeyState -master 'salt' -minion 'server2022a' -confirm:$false
|
||||
#>
|
||||
[cmdletbinding(SupportsShouldProcess=$true,ConfirmImpact='High')]
|
||||
param(
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][string]$master,
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][string]$minion
|
||||
)
|
||||
|
||||
begin {
|
||||
$collection = @()
|
||||
}
|
||||
|
||||
process {
|
||||
if ($PSCmdlet.ShouldProcess("$master : $minion" , 'delete')) {
|
||||
$collection += ,@($master, $minion)
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
$kwarg = @{}
|
||||
$kwarg.Add('state','delete')
|
||||
$kwarg.Add('minions', @( $collection ) )
|
||||
|
||||
(Get-SscData minions set_minion_key_state $kwarg).task_ids
|
||||
}
|
||||
}
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
103
Modules/Start-UNMAP/Start-UNMAP.psm1
Normal file
103
Modules/Start-UNMAP/Start-UNMAP.psm1
Normal file
@@ -0,0 +1,103 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
938
Modules/VAMI/VAMI.psm1
Executable file
938
Modules/VAMI/VAMI.psm1
Executable file
@@ -0,0 +1,938 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
|
||||
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, releasedate
|
||||
|
||||
$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;
|
||||
ReleaseDate = $results.releasedate;
|
||||
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;
|
||||
BashTimeout = $shellAccess.timeout;
|
||||
SSH = $sshAccess
|
||||
}
|
||||
$accessResult
|
||||
}
|
||||
|
||||
Function Get-VAMITime {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 16, 2020
|
||||
===========================================================================
|
||||
.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
|
||||
.NOTES
|
||||
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs
|
||||
#>
|
||||
$systemTimeAPI = ( Get-VAMIServiceAPI -NameFilter "system.time")
|
||||
$timeResults = $systemTimeAPI.get()
|
||||
|
||||
$timeSyncMode = ( Get-VAMIServiceAPI -NameFilter "timesync").get()
|
||||
if ($timeSyncMode.mode) {
|
||||
$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-VAMIServiceAPI -NameFilter "ntp").get()
|
||||
if ($ntpServers.servers) {
|
||||
$timeResult.NTPServers = $ntpServers.servers
|
||||
$timeResult.NTPStatus = $ntpServers.status
|
||||
} else {
|
||||
$timeResult.NTPServers = $ntpServers
|
||||
$timeResult.NTPStatus = ( Get-VAMIServiceAPI -NameFilter "ntp").test(( Get-VAMIServiceAPI -NameFilter "ntp").get()).status
|
||||
}
|
||||
}
|
||||
$timeResult
|
||||
}
|
||||
|
||||
Function Set-VAMITimeSync {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Inspired by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
Created by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function sets 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!
|
||||
Set-VAMITimeSync -SyncMode "NTP" -TimeZone "US/Pacific" -NTPServers "10.0.0.10,10.0.0.11,10.0.0.12"
|
||||
.NOTES
|
||||
Create script to Set NTP for Newer VCSA. Script supports 6.7 VCSAs
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[ValidateSet('Disabled', 'NTP', 'Host')]
|
||||
[String]$SyncMode,
|
||||
[Parameter(Mandatory=$False,HelpMessage="TimeZone Name needs to be in Posix Naming / Unix format")]
|
||||
[String]$TimeZone,
|
||||
[Parameter(Mandatory=$false,HelpMessage="NTP Servers need to be either a string separated by ',' or an array of servers")]
|
||||
$NTPServers
|
||||
)
|
||||
|
||||
$timeSyncMode = ( Get-VAMIServiceAPI -NameFilter "timesync").get()
|
||||
if ($timeSyncMode.gettype().name -eq "PSCustomObject") {
|
||||
if ($SyncMode.ToUpper() -ne $timeSyncMode.mode.toupper()) {
|
||||
$timesyncapi = (Get-VAMIServiceAPI -NameFilter "timesync")
|
||||
$timesyncconfig = $timesyncapi.help.set.config.createexample()
|
||||
$timesyncconfig = $Sync
|
||||
$timesyncapi.set($timesyncconfig)
|
||||
}
|
||||
} else {
|
||||
if ($SyncMode.ToUpper() -ne $timeSyncMode.toupper()) {
|
||||
$timesyncapi = (Get-VAMIServiceAPI -NameFilter "timesync")
|
||||
$timesyncapi.set($Sync)
|
||||
}
|
||||
if ($NTPServers) {
|
||||
$ntpapi = (Get-VAMIServiceAPI -NameFilter "ntp")
|
||||
if ($NTPServers.gettype().Name -eq "String") {
|
||||
$NTPServersArray = ($NTPServers -split ",").trim()
|
||||
} else {
|
||||
$NTPServersArray = $NTPServers
|
||||
}
|
||||
if ($NTPServersArray -ne $ntpapi.get()) {
|
||||
$ntpapi.set($NTPServersArray)
|
||||
}
|
||||
}
|
||||
if ($TimeZone) {
|
||||
$timezoneapi = (Get-VAMIServiceAPI -NameFilter "timezone")
|
||||
if ($TimeZone -ne ($timezoneapi.get())) {
|
||||
$timezoneapi.set($TimeZone)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-VAMINetwork {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
Modifed by: Michael Dunsdon, Mathieu Allegret
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
===========================================================================
|
||||
.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
|
||||
.NOTES
|
||||
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs
|
||||
#>
|
||||
$netResults = @()
|
||||
|
||||
$Hostname = (Get-VAMIServiceAPI -NameFilter "dns.hostname").get()
|
||||
$dns = (Get-VAMIServiceAPI -NameFilter "dns.servers").get()
|
||||
|
||||
$interfaces = (Get-VAMIServiceAPI -NameFilter "interfaces").list()
|
||||
foreach ($interface in $interfaces) {
|
||||
$ipv4API = (Get-VAMIServiceAPI -NameFilter "ipv4")
|
||||
if ($ipv4API.help.get.psobject.properties.name -like "*_*") {
|
||||
$ipv4result = $ipv4API.get($interface.Name)
|
||||
$Updateable = $ipv4result.configurable
|
||||
} else {
|
||||
$ipv4result = $ipv4API.get(@($interface.Name))
|
||||
$Updateable = $ipv4result.updateable
|
||||
}
|
||||
$interfaceResult = [pscustomobject] @{
|
||||
Hostname = $Hostname
|
||||
Inteface = $interface.name
|
||||
MAC = $interface.mac
|
||||
Status = $interface.status
|
||||
Mode = $ipv4result.mode
|
||||
IP = $ipv4result.address
|
||||
Prefix = $ipv4result.prefix
|
||||
Gateway = $ipv4result.default_gateway
|
||||
DNSServers = $dns.servers
|
||||
Updateable = $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-Object {[int]$_.disk.toString()}) {
|
||||
$disk | Select-Object 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
|
||||
Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 16, 2020
|
||||
===========================================================================
|
||||
.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
|
||||
.NOTES
|
||||
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs.
|
||||
Also modifed the static list of filesystems to be more dynamic in nature to account for the differences in VCSA versions.
|
||||
#>
|
||||
|
||||
$monitoringAPI = Get-CisService 'com.vmware.appliance.monitoring'
|
||||
$querySpec = $monitoringAPI.help.query.item.CreateExample()
|
||||
|
||||
# List of IDs from Get-VAMIStatsList to query
|
||||
$querySpec.Names = ($monitoringAPI.list() | Where-Object {($_.name -like "*storage.used.filesystem*") -or ($_.name -like "*storage.totalsize.filesystem*") } | Select-Object id | Sort-Object -Property id).id.value
|
||||
|
||||
# Tuple (Filesystem Name, Used, Total) to store results
|
||||
$storageStats = @{
|
||||
"archive"=@{"name"="/storage/archive";"used"=0;"total"=0};
|
||||
"autodeploy"=@{"name"="/storage/autodeploy";"used"=0;"total"=0};
|
||||
"boot"=@{"name"="/boot";"used"=0;"total"=0};
|
||||
"core"=@{"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};
|
||||
"db"=@{"name"="/storage/db";"used"=0;"total"=0};
|
||||
"seat"=@{"name"="/storage/seat";"used"=0;"total"=0};
|
||||
"dblog"=@{"name"="/storage/dblog";"used"=0;"total"=0};
|
||||
"swap"=@{"name"="swap";"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-Object * -ExcludeProperty Help
|
||||
|
||||
foreach ($queryResult in $queryResults) {
|
||||
# Update hash if its used storage results
|
||||
$key = ((($queryResult.name).toString()).split(".")[-1]) -replace "coredump","core" -replace "vcdb_","" -replace "core_inventory","db" -replace "transaction_log","dblog"
|
||||
$value = [Math]::Round([int]($queryResult.data[1]).toString()/1MB,2)
|
||||
if($queryResult.name -match "used") {
|
||||
$storageStats[$key]["used"] = $value
|
||||
# Update hash if its total storage results
|
||||
} else {
|
||||
$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
|
||||
Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 16, 2020
|
||||
===========================================================================
|
||||
.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
|
||||
.NOTES
|
||||
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs.
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$false,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
$userAPI = Get-VAMIServiceAPI -NameFilter "accounts"
|
||||
$UserResults = @()
|
||||
|
||||
# Get a list of users
|
||||
try {
|
||||
$Users = $UserAPI.list()
|
||||
} catch {
|
||||
write-error $_
|
||||
}
|
||||
|
||||
# Apply filtering if Name input is provided
|
||||
if ($Name -ne '' -AND $Name -ne $null) {
|
||||
# For 6.5 API, the username is part of the list returnset; for 6.7/7.x API the value from the list is the username. Because of this we will use an OR filter to account for either case.
|
||||
$Users = $Users | Where-Object {$_.username -eq $name -OR $_.value -eq $name}
|
||||
}
|
||||
|
||||
if ($Users.status) {
|
||||
# This is for 6.5 API, which has a status property; in newer API response there is an enabled property with values of True/False
|
||||
foreach ($User in $Users) {
|
||||
$UserString = [pscustomobject] @{
|
||||
User = $User.username
|
||||
Name = $User.fullname
|
||||
Email = $User.email
|
||||
Enabled = if ($User.status -eq 'enabled' ) { $true } else { $false }
|
||||
Status = $User.status
|
||||
LastPasswordChange = $null
|
||||
PasswordExpiresAt = $null
|
||||
PasswordStatus = $User.passwordstatus
|
||||
Roles = @($User.role)
|
||||
}
|
||||
$UserResults += $UserString
|
||||
}
|
||||
} else {
|
||||
# This is for 6.7/7.0+ API response
|
||||
foreach ($User in $Users) {
|
||||
$UserInfo = $userAPI.get($User.Value)
|
||||
$UserString = [pscustomobject] @{
|
||||
User = $User.value
|
||||
Name = $UserInfo.fullname
|
||||
Email = $UserInfo.email
|
||||
Enabled = $UserInfo.enabled
|
||||
Status = if ($userInfo.enabled ) { 'enabled' } else { 'disabled' }
|
||||
LastPasswordChange = $UserInfo.last_password_change
|
||||
PasswordExpiresAt = $UserInfo.password_expires_at
|
||||
PasswordStatus = if ($UserInfo.has_password) { if ((!!$UserInfo.password_expires_at) -and ( (Get-Date) -lt [datetime]$UserInfo.password_expires_at)) {'valid'} else {'expired'}} else { 'notset'}
|
||||
Roles = $UserInfo.roles
|
||||
}
|
||||
$UserResults += $UserString
|
||||
}
|
||||
}
|
||||
$UserResults
|
||||
}
|
||||
|
||||
Function New-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 16, 2020
|
||||
===========================================================================
|
||||
.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!" -passwordexpires -passwordexpiresat "1/1/1970" -maxpasswordage 90
|
||||
.NOTES
|
||||
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs.
|
||||
Also added new Parameters to script.
|
||||
#>
|
||||
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,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[switch]$PasswordExpires,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[String]$PasswordExpiresAt = $null,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[String]$MaxPasswordAge = 90
|
||||
)
|
||||
|
||||
$userAPI = Get-VAMIServiceAPI -NameFilter "accounts"
|
||||
if ($userAPI.name -eq 'com.vmware.appliance.techpreview.localaccounts.user') {
|
||||
$CreateSpec = $UserAPI.Help.add.config.Create()
|
||||
} else {
|
||||
$CreateSpec = $UserAPI.Help.create.config.Create()
|
||||
}
|
||||
|
||||
$CreateSpec.email = $Email
|
||||
$CreateSpec.password = [VMware.VimAutomation.Cis.Core.Types.V1.Secret]$Password
|
||||
|
||||
if ($CreateSpec.psobject.properties.name -contains "username") {
|
||||
# This is for 6.5 API
|
||||
$CreateSpec.username = $Name
|
||||
$CreateSpec.fullname = $FullName
|
||||
$CreateSpec.role = $Role
|
||||
try {
|
||||
Write-Host "Creating new user $Name ..."
|
||||
$UserAPI.add($CreateSpec)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
} else {
|
||||
# This is for 6.7/7.0+ API
|
||||
$CreateSpec.full_name = $FullName
|
||||
$CreateSpec.roles = @($Role)
|
||||
$CreateSpec.password_expires = [string]$PasswordExpires
|
||||
$CreateSpec.password_expires_at = $PasswordExpiresAt
|
||||
$CreateSpec.max_days_between_password_change = $MaxPasswordAge
|
||||
try {
|
||||
Write-Host "Creating new user $Name ..."
|
||||
$UserAPI.create($Name, $CreateSpec)
|
||||
} catch {
|
||||
Write-Error $_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Update-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Inspired by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
Created by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function to update fields of a 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 update fields of a VAMI local user
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Update-VAMIUser -name lamw -fullname "William Lam" -role "operator" -email "lamw@virtuallyghetto.com" -password "VMware1!" -passwordexpires -passwordexpiresat "1/1/1970" -maxpasswordage 90
|
||||
.NOTES
|
||||
Created script to allow updating of an exisiting user account. Script supports 6.5 and 6.7 VCSAs.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[String]$FullName,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[ValidateSet("admin","operator","superAdmin")]
|
||||
[String]$Role,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[String]$Email="",
|
||||
[Parameter(Mandatory=$false)]
|
||||
[String]$Password = $null,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[switch]$PasswordExpires,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[String]$PasswordExpiresAt = $null,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[String]$MaxPasswordAge = 90
|
||||
)
|
||||
|
||||
$userAPI = Get-VAMIServiceAPI -NameFilter "accounts"
|
||||
$UpdateSpec = $UserAPI.Help.set.config.CreateExample()
|
||||
|
||||
$UpdateSpec.fullname = $FullName
|
||||
$UpdateSpec.role = $Role
|
||||
$UpdateSpec.email = $Email
|
||||
|
||||
if ($UpdateSpec.psobject.properties.name -contains "username") {
|
||||
$UpdateSpec.username = $Name
|
||||
try {
|
||||
Write-Host "Updating Settings for user $Name ..."
|
||||
$UserAPI.set($UpdateSpec)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
} else {
|
||||
$UpdateSpec.password = [VMware.VimAutomation.Cis.Core.Types.V1.Secret]$Password
|
||||
$UpdateSpec.password_expires = $PasswordExpires
|
||||
$UpdateSpec.password_expires_at = $PasswordExpiresAt
|
||||
$UpdateSpec.max_days_between_password_change = $MaxPasswordAge
|
||||
try {
|
||||
Write-Host "Updating Settings for user $Name ..."
|
||||
$UserAPI.update($Name, $UpdateSpec)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Remove-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
Modifed by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
===========================================================================
|
||||
.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
|
||||
.NOTES
|
||||
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs.
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]$Name
|
||||
)
|
||||
Begin {}
|
||||
Process{
|
||||
if($PSCmdlet.ShouldProcess($Name,'Delete')) {
|
||||
$userAPI = Get-VAMIServiceAPI -NameFilter "accounts"
|
||||
try {
|
||||
Write-Host "Deleting user $name ..."
|
||||
$userAPI.delete($name)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
}
|
||||
End{}
|
||||
}
|
||||
|
||||
Function Get-VAMIServiceAPI {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Inspired by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
Created by: Michael Dunsdon
|
||||
Twitter: @MJDunsdon
|
||||
Date: September 21, 2020
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function returns the Service Api Based on a String of Service Name.
|
||||
.DESCRIPTION
|
||||
Function to find and get service api based on service name string
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIUser -NameFilter "accounts"
|
||||
.NOTES
|
||||
Script supports 6.5 and 6.7 VCSAs.
|
||||
Function Gets all Service Api Names and filters the list based on NameFilter
|
||||
If Multiple Serivces are returned it takes the Top one.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]$NameFilter
|
||||
)
|
||||
|
||||
$ServiceAPI = Get-CisService | Where-Object {$_.name -like "*$($NameFilter)*"}
|
||||
if (($ServiceAPI.count -gt 1) -and $NameFilter) {
|
||||
$ServiceAPI = ($ServiceAPI | Sort-Object -Property Name)[0]
|
||||
}
|
||||
return $ServiceAPI
|
||||
}
|
||||
417
Modules/VCHA/VCHA.psm1
Normal file
417
Modules/VCHA/VCHA.psm1
Normal file
@@ -0,0 +1,417 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
72
Modules/VCSA/VCSA.psm1
Normal file
72
Modules/VCSA/VCSA.psm1
Normal file
@@ -0,0 +1,72 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
Function Get-VCSAPasswordPolicy {
|
||||
<#
|
||||
.DESCRIPTION Retrieves vCenter Server Appliance SSO and Local OS Password Policy Configuration
|
||||
.NOTES Author: William Lam
|
||||
.PARAMETER VCSAName
|
||||
Inventory name of the VCSA VM
|
||||
.PARAMETER VCSARootPassword
|
||||
Root password for VCSA VM
|
||||
.PARAMETER SSODomain
|
||||
SSO Domain of the VCSA VM
|
||||
.PARAMETER SSOPassword
|
||||
Administrator password for the SSO Domain of the VCSA VM
|
||||
.EXAMPLE
|
||||
Get-VCSAPasswordPolicy -VCSAName "MGMT-VCSA-01" -VCSARootPassword "VMware1!" -SSODomain "vsphere.local" -SSOPassword "VMware1!"
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$true)][String]$VCSAName,
|
||||
[Parameter(Mandatory=$true)][String]$VCSARootPassword,
|
||||
[Parameter(Mandatory=$true)][String]$SSODomain,
|
||||
[Parameter(Mandatory=$true)][String]$SSOPassword
|
||||
)
|
||||
|
||||
$vm = Get-Vm -Name $VCSAName
|
||||
|
||||
if($vm) {
|
||||
$a,$b = $SSODomain.split(".")
|
||||
|
||||
$ssoPasswordPolicy = Invoke-VMScript -ScriptText "/opt/likewise/bin/ldapsearch -h localhost -w $SSOPassword -x -D `"cn=Administrator,cn=Users,dc=$a,dc=$b`" -b `"cn=password and lockout policy,dc=$a,dc=$b`" | grep vmwPassword" -vm $vm -GuestUser "root" -GuestPassword $VCSARootPassword
|
||||
$localOSPasswordPolicy = Invoke-VMScript -ScriptText "cat /etc/login.defs | grep -v '#' | grep PASS" -vm $vm -GuestUser "root" -GuestPassword $VCSARootPassword
|
||||
|
||||
Write-Host -ForegroundColor green "`nSSO Password Policy: "
|
||||
$ssoPasswordPolicy
|
||||
|
||||
Write-Host -ForegroundColor green "`nLocalOS Password Policy: "
|
||||
$localOSPasswordPolicy
|
||||
} else {
|
||||
Write-Host "`nUnable to find VCSA named $VCSAName"
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-VCSAIdentitySource {
|
||||
<#
|
||||
.DESCRIPTION Retrieves vCenter Server Appliance Identity Source Configuration
|
||||
.NOTES Author: William Lam
|
||||
.PARAMETER VCSAName
|
||||
Inventory name of the VCSA VM
|
||||
.PARAMETER VCSARootPassword
|
||||
Root password for VCSA VM
|
||||
.EXAMPLE
|
||||
Get-VCSAIdentitySource -VCSAName "MGMT-VCSA-01" -VCSARootPassword "VMware1!"
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$true)][String]$VCSAName,
|
||||
[Parameter(Mandatory=$true)][String]$VCSARootPassword
|
||||
)
|
||||
|
||||
$vm = Get-Vm -Name $VCSAName
|
||||
|
||||
if($vm) {
|
||||
$identitySources = Invoke-VMScript -ScriptText "/opt/vmware/bin/sso-config.sh -get_identity_sources 2> /dev/null | sed -ne '/^*/,$ p'" -vm $vm -GuestUser "root" -GuestPassword $VCSARootPassword
|
||||
|
||||
Write-Host -ForegroundColor green "`nIdentity Sources: "
|
||||
$identitySources
|
||||
|
||||
} else {
|
||||
Write-Host "`nUnable to find VCSA named $VCSAName"
|
||||
}
|
||||
}
|
||||
7
Modules/VISecret/README.md
Normal file
7
Modules/VISecret/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Example module for using SecretManagement and SecretStore to save PowerCLI credentials
|
||||
|
||||
|
||||
|
||||
This module demonstrates how users can use the the Microsoft.PowerShell.SecretManagement and Microsoft.PowerShell.SecretStore modules to save their PowerCLI credentials.
|
||||
|
||||
The module supports PowerShell 5.1 and PowerShell 7.0 and above.
|
||||
138
Modules/VISecret/VMware.VISecret.psd1
Normal file
138
Modules/VISecret/VMware.VISecret.psd1
Normal file
@@ -0,0 +1,138 @@
|
||||
#
|
||||
# Module manifest for module 'VMware.VISecret'
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'VMware.VISecret.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.0.0.0'
|
||||
|
||||
# Supported PSEditions
|
||||
CompatiblePSEditions = @('Desktop', 'Core')
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '66124b00-4095-4a1f-9940-f91622009b15'
|
||||
|
||||
# Author of this module
|
||||
Author = 'VMware'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'VMware'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = 'Copyright (c) VMware, Inc. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = 'Module to enable easy use of Microsoft.PowerShell.SecretManagement module in VMware context'
|
||||
|
||||
# Minimum version of the PowerShell engine required by this module
|
||||
PowerShellVersion = '5.1'
|
||||
|
||||
# Name of the PowerShell host required by this module
|
||||
# PowerShellHostName = ''
|
||||
|
||||
# Minimum version of the PowerShell host required by this module
|
||||
# PowerShellHostVersion = ''
|
||||
|
||||
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# DotNetFrameworkVersion = ''
|
||||
|
||||
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# 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 = @(
|
||||
@{"ModuleName"="VMware.VimAutomation.Core";"ModuleVersion"="1.0.0.0"}
|
||||
@{"ModuleName"="Microsoft.PowerShell.SecretManagement";"ModuleVersion"="1.1.2"}
|
||||
@{"ModuleName"="Microsoft.PowerShell.SecretStore";"ModuleVersion"="1.0.6"}
|
||||
)
|
||||
|
||||
# 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, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
|
||||
FunctionsToExport = @(
|
||||
'Initialize-VISecret',
|
||||
'New-VISecret',
|
||||
'Get-VISecret',
|
||||
'Remove-VISecret',
|
||||
'Connect-VIServerWithSecret'
|
||||
)
|
||||
|
||||
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
|
||||
CmdletsToExport = @()
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = @()
|
||||
|
||||
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
|
||||
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 = ''
|
||||
|
||||
# A URL to an icon representing this module.
|
||||
# IconUri = ''
|
||||
|
||||
# ReleaseNotes of this module
|
||||
# ReleaseNotes = ''
|
||||
|
||||
# Prerelease string of this module
|
||||
# Prerelease = ''
|
||||
|
||||
# Flag to indicate whether the module requires explicit user acceptance for install/update/save
|
||||
# RequireLicenseAcceptance = $false
|
||||
|
||||
# External dependent modules of this module
|
||||
# ExternalModuleDependencies = @()
|
||||
|
||||
} # 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 = ''
|
||||
|
||||
}
|
||||
|
||||
314
Modules/VISecret/VMware.VISecret.psm1
Normal file
314
Modules/VISecret/VMware.VISecret.psm1
Normal file
@@ -0,0 +1,314 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This cmdlet downloads the dependencies and intializes the default settings of the VISecret module
|
||||
|
||||
.PARAMETER Vault
|
||||
The vault to save the credentials to. The default value is "VMwareSecretStore"
|
||||
|
||||
.DESCRIPTION
|
||||
This cmdlet downloads the dependecies and initializes the default settings of the VISecret module.
|
||||
It uses Microsoft.PowerShell.SecretStore as a default vault and sets it in no password mode, so that
|
||||
the credentials are encrypted, but the user is not prompted for a password. If you want to use a different
|
||||
vault or to use it with a password you should initialize those settings manually and not use this cmdlet.
|
||||
|
||||
.EXAMPLE
|
||||
PS C:\> Initialize-VISecret
|
||||
|
||||
Initializes the default settings of the VISecret module
|
||||
#>
|
||||
function Initialize-VISecret {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$Vault = "VMwareSecretStore"
|
||||
)
|
||||
|
||||
process {
|
||||
Set-SecretStoreConfiguration -Scope CurrentUser -Authentication None -Interaction None -Confirm:$false
|
||||
|
||||
Register-SecretVault -Name $Vault -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This cmdlet saves new credential in the secret vault or updates it if it already exists.
|
||||
|
||||
.DESCRIPTION
|
||||
This cmdlet saves new credential in the secret vault or updates it if it already exists.
|
||||
|
||||
.PARAMETER Server
|
||||
The IP address or the hostname of the server to save the credential for
|
||||
|
||||
.PARAMETER Password
|
||||
The password to be saved in the secret vault
|
||||
|
||||
.PARAMETER SecureStringPassword
|
||||
The SecureString password to be saved in the secret vault
|
||||
|
||||
.PARAMETER User
|
||||
The username for which to save the credential
|
||||
|
||||
.PARAMETER Vault
|
||||
The vault to save the credential to. The default value is "VMwareSecretStore"
|
||||
|
||||
.EXAMPLE
|
||||
PS C:\> New-VISecret -Server 10.10.10.10 -User administrator@vsphere.local -password pass
|
||||
|
||||
Saves the password for the administrator@vsphere.local user on the 10.10.10.10 server in the secret vault
|
||||
|
||||
#>
|
||||
function New-VISecret {
|
||||
[CmdletBinding()]
|
||||
[Alias("Set-VISecret")]
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Server,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$User,
|
||||
[string]$Password,
|
||||
[securestring]$SecureStringPassword,
|
||||
[string]$Vault
|
||||
)
|
||||
|
||||
begin {
|
||||
if ([string]::IsNullOrWhiteSpace($password) -and (-not $secureStringPassword)) {
|
||||
Throw "Either Password or SecureStringPassword parameter needs to be specified"
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($password) -and $secureStringPassword) {
|
||||
Throw "Password and SecureStringPassword parameters cannot be both specified at the same time"
|
||||
}
|
||||
}
|
||||
|
||||
process {
|
||||
$params = @{
|
||||
"Name" = "VISecret|"+$server+"|"+$User
|
||||
}
|
||||
if ($password) {
|
||||
$params += @{"Secret" = $password}
|
||||
} elseif ($secureStringPassword) {
|
||||
$params += @{"SecureStringSecret" = $secureStringPassword}
|
||||
} elseif ($Vault) {
|
||||
$params += @{"Vault" = $Vault}
|
||||
}
|
||||
Set-Secret @params
|
||||
}
|
||||
}
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Retrieves a credential from the secret store vault.
|
||||
|
||||
.DESCRIPTION
|
||||
Retrieves a credential from the secret store vault.
|
||||
|
||||
.PARAMETER Server
|
||||
The IP address or the hostname of the server to retrieve the credential for
|
||||
|
||||
.PARAMETER User
|
||||
The username for which to retrieve the credential
|
||||
|
||||
.PARAMETER AsPlainText
|
||||
Specifies that a credential should be returned as a String (in plain text) instead of a SecureString.
|
||||
To ensure security, you should avoid using plaintext strings whenever possible.
|
||||
|
||||
.PARAMETER Vault
|
||||
The vault to retrieve the credential from. The default value is "VMwareSecretStore"
|
||||
|
||||
.EXAMPLE
|
||||
PS C:\> $securePassword = Get-VISecret -Server 10.10.10.10 -User administrator@vsphere.local
|
||||
|
||||
Retrieves the password for the administrator@vsphere.local user on the 10.10.10.10 server from the secret vault
|
||||
#>
|
||||
function Get-VISecret {
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Server,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$User,
|
||||
[switch]$AsPlainText,
|
||||
[string]$Vault
|
||||
)
|
||||
|
||||
process {
|
||||
$params = @{
|
||||
"Name" = "VISecret|"+$server+"|"+$User
|
||||
}
|
||||
if ($AsPlainText.IsPresent) {
|
||||
$params += @{"AsPlainText" = $AsPlainText.ToBool()}
|
||||
} elseif ($Vault) {
|
||||
$params += @{"Vault" = $Vault}
|
||||
}
|
||||
Get-Secret @params
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Removes a credential from the vault.
|
||||
|
||||
.DESCRIPTION
|
||||
Removes a credential from the vault.
|
||||
|
||||
.PARAMETER Server
|
||||
The IP address or the hostname of the server to remove the credential for
|
||||
|
||||
.PARAMETER User
|
||||
The username for which to remove the credential
|
||||
|
||||
.PARAMETER Vault
|
||||
The vault to remove the credential from. The default value is "VMwareSecretStore"
|
||||
|
||||
.EXAMPLE
|
||||
PS C:\> Remove-VISecret -Server 10.10.10.10 -User administrator@vsphere.local
|
||||
|
||||
Removes the password for the administrator@vsphere.local user on the 10.10.10.10 server from the vault
|
||||
#>
|
||||
function Remove-VISecret {
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Server,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$User,
|
||||
[string]$Vault
|
||||
)
|
||||
|
||||
process {
|
||||
$params = @{
|
||||
"Name" = "VISecret|"+$server+"|"+$User
|
||||
}
|
||||
if ($Vault) {
|
||||
$params += @{"Vault" = $Vault}
|
||||
}
|
||||
Remove-Secret @params
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This cmdlet establishes a connection to a vCenter Server system.
|
||||
|
||||
.DESCRIPTION
|
||||
This cmdlet establishes a connection to a vCenter Server system.
|
||||
If a credential object or username and password the cmdlet uses them to connect and if the
|
||||
-SaveCredential parameter is specified saves them in the vault. If only username
|
||||
is specified the cmdlet uses the server name and the user name to search for the password in the
|
||||
vault.
|
||||
|
||||
.PARAMETER Server
|
||||
Specifies the IP address or the DNS name of the vSphere server to which you want to connect.
|
||||
|
||||
.PARAMETER User
|
||||
Specifies the user name you want to use for authenticating with the server.
|
||||
|
||||
.PARAMETER Password
|
||||
Specifies the password you want to use for authenticating with the server.
|
||||
|
||||
.PARAMETER Credential
|
||||
Specifies a PSCredential object that contains credentials for authenticating with the server.
|
||||
|
||||
.PARAMETER AllLinked
|
||||
Indicates whether you want to connect to vCenter Server in linked mode. If you specify $true
|
||||
for the -AllLinked parameter and the server to which you want to connect is a part of a federation
|
||||
vCenter Server, you'll be connected to all members of the linked vCenter Server. To use this
|
||||
option, PowerCLI must be configured to work in multiple servers connection mode. To configure
|
||||
PowerCLI to support multiple servers connection, specify Multiple for the DefaultVIServerMode
|
||||
parameter of the Set-PowerCLIConfiguration cmdlet.
|
||||
|
||||
.PARAMETER Force
|
||||
Suppresses all user interface prompts during the cmdlet execution.
|
||||
|
||||
.PARAMETER NotDefault
|
||||
Indicates that you do not want to include the server to which you connect into the $defaultVIServers variable.
|
||||
|
||||
.PARAMETER Port
|
||||
Specifies the port on the server you want to use for the connection.
|
||||
|
||||
.PARAMETER Protocol
|
||||
Specifies the Internet protocol you want to use for the connection. It can be either http or https.
|
||||
|
||||
.PARAMETER SaveCredentials
|
||||
Indicates that you want to save the specified credentials in the vault.
|
||||
|
||||
.PARAMETER Vault
|
||||
The vault to save the credential to. The default value is "VMwareSecretStore"
|
||||
|
||||
.EXAMPLE
|
||||
Connect-VIServer -Server 10.10.10.10 -User administrator@vsphere.local
|
||||
|
||||
Connects to a vSphere server using the saved credential for the specified user
|
||||
|
||||
.EXAMPLE
|
||||
Connect-VIServer -Server 10.10.10.10 -User administrator@vsphere.local -Password pass -SaveCredential
|
||||
|
||||
Connects to a vSphere server using the specified username and password and saves them in the vault
|
||||
#>
|
||||
function Connect-VIServerWithSecret {
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Server,
|
||||
[string]$User,
|
||||
[string]$Password,
|
||||
[pscredential]$Credential,
|
||||
[switch]$AllLinked,
|
||||
[switch]$Force,
|
||||
[switch]$NotDefault,
|
||||
[int]$Port,
|
||||
[string]$Protocol,
|
||||
[switch]$SaveCredentials,
|
||||
[string]$Vault
|
||||
)
|
||||
|
||||
begin {
|
||||
if ([string]::IsNullOrWhiteSpace($User) -and (-not $Credential)) {
|
||||
if ($global:defaultUser) {
|
||||
$User = $global:defaultUser
|
||||
} else {
|
||||
Throw "Either User or Credential parameters needs to be specified"
|
||||
}
|
||||
}
|
||||
|
||||
if ((-not [string]::IsNullOrWhiteSpace($User) -or -not [string]::IsNullOrWhiteSpace($Password)) -and $Credential) {
|
||||
Throw "User/Password and Credential parameters cannot be both specified at the same time"
|
||||
}
|
||||
}
|
||||
|
||||
process {
|
||||
$params = @{
|
||||
"Server" = $Server
|
||||
"AllLinked" = $AllLinked
|
||||
"Force" = $Force
|
||||
"NotDefault" = $NotDefault
|
||||
}
|
||||
if ($Protocol) {
|
||||
$params += @{"Protocol" = $Protocol}
|
||||
}
|
||||
if ($Port) {
|
||||
$params += @{"Port" = $Port}
|
||||
}
|
||||
if ($User) {
|
||||
if (-not $Password) {
|
||||
if ($Vault) {
|
||||
$secret = Get-Secret -Name ("VISecret|"+$server+"|"+$User) -Vault $Vault -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
$secret = Get-Secret -Name ("VISecret|"+$server+"|"+$User) -ErrorAction SilentlyContinue
|
||||
}
|
||||
if (-not $secret) {
|
||||
Throw "No password has been found for this server and user in the password vault"
|
||||
}
|
||||
$Credential = New-Object System.Management.Automation.PSCredential ($User, $secret)
|
||||
}
|
||||
else {
|
||||
$securePass = ConvertTo-SecureString -String $Password -AsPlainText
|
||||
$Credential = New-Object System.Management.Automation.PSCredential ($User, $securePass)
|
||||
}
|
||||
}
|
||||
$params += @{"Credential" = $Credential}
|
||||
Connect-VIServer @params
|
||||
if ($SaveCredentials) {
|
||||
New-VISecret -Server $Server -User $User -SecureStringPassword $Credential.Password -Vault $Vault
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
326
Modules/VMCPFunctions/VMCPFunctions.psm1
Normal file
326
Modules/VMCPFunctions/VMCPFunctions.psm1
Normal file
@@ -0,0 +1,326 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
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 * $partInfo[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 = ($expOpt[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
|
||||
1238
Modules/VMToolsManagement/VMToolsManagement.psm1
Normal file
1238
Modules/VMToolsManagement/VMToolsManagement.psm1
Normal file
File diff suppressed because it is too large
Load Diff
21
Modules/VMware-vCD-Module/LICENSE
Normal file
21
Modules/VMware-vCD-Module/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Markus Kraus
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
|
||||
|
||||
129
Modules/VMware-vCD-Module/VMware-vCD-Module.psd1
Normal file
129
Modules/VMware-vCD-Module/VMware-vCD-Module.psd1
Normal file
@@ -0,0 +1,129 @@
|
||||
#
|
||||
# Modulmanifest f<>r das Modul "PSGet_VMware-vCD-Module"
|
||||
#
|
||||
# Generiert von: Markus
|
||||
#
|
||||
# Generiert am: 6/11/2017
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Die diesem Manifest zugeordnete Skript- oder Bin<69>rmoduldatei.
|
||||
# RootModule = ''
|
||||
|
||||
# Die Versionsnummer dieses Moduls
|
||||
ModuleVersion = '1.3.0'
|
||||
|
||||
# ID zur eindeutigen Kennzeichnung dieses Moduls
|
||||
GUID = '1ef8a2de-ca22-4c88-8cdb-e00f35007d2a'
|
||||
|
||||
# Autor dieses Moduls
|
||||
Author = 'Markus Kraus'
|
||||
|
||||
# Unternehmen oder Hersteller dieses Moduls
|
||||
CompanyName = 'mycloudrevolution.com'
|
||||
|
||||
# Urheberrechtserkl<6B>rung f<>r dieses Modul
|
||||
Copyright = '(c) 2017 Markus. Alle Rechte vorbehalten.'
|
||||
|
||||
# Beschreibung der von diesem Modul bereitgestellten Funktionen
|
||||
Description = 'This a POwerShell Module based on VMware PowerCLI vCloud Director Module to extend its function'
|
||||
|
||||
# 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 = @('VMware.VimAutomation.Cloud')
|
||||
|
||||
# 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<65>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',
|
||||
'functions\New-MyOrgNetwork.psm1'
|
||||
)
|
||||
|
||||
# Aus diesem Modul zu exportierende Funktionen
|
||||
FunctionsToExport = 'Invoke-MyOnBoarding', 'New-MyEdgeGateway', 'New-MyOrg', 'New-MyOrgAdmin', 'New-MyOrgVdc', 'New-MyOrgNetwork'
|
||||
|
||||
# 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 <20>bergeben werden sollen. Diese k<>nnen auch eine PSData-Hashtabelle mit zus<75>tzlichen von PowerShell verwendeten Modulmetadaten enthalten.
|
||||
PrivateData = @{
|
||||
|
||||
PSData = @{
|
||||
|
||||
# Tags applied to this module. These help with module discovery in online galleries.
|
||||
Tags = @('VMware', 'vCloud', 'PowerCLI', 'vCloudDirector', 'Automation', 'EdgeGateway', 'OrgNetwork')
|
||||
|
||||
# A URL to the license for this module.
|
||||
LicenseUri = 'https://github.com/mycloudrevolution/VMware-vCD-Module/blob/master/LICENSE'
|
||||
|
||||
# A URL to the main website for this project.
|
||||
ProjectUri = 'https://github.com/mycloudrevolution/VMware-vCD-Module'
|
||||
|
||||
# A URL to an icon representing this module.
|
||||
IconUri = 'https://github.com/mycloudrevolution/VMware-vCD-Module/blob/master/media/vCD_Small.png'
|
||||
|
||||
# ReleaseNotes of this module
|
||||
# ReleaseNotes = ''
|
||||
|
||||
# External dependent modules of this module
|
||||
ExternalModuleDependencies = 'VMware.VimAutomation.Cloud'
|
||||
|
||||
} # End of PSData hashtable
|
||||
|
||||
} # End of PrivateData hashtable
|
||||
|
||||
# HelpInfo-URI dieses Moduls
|
||||
# HelpInfoURI = ''
|
||||
|
||||
# Standardpr<70>fix f<>r Befehle, die aus diesem Modul exportiert werden. Das Standardpr<70>fix kann mit "Import-Module -Prefix" <20>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"
|
||||
}
|
||||
}
|
||||
193
Modules/VMware-vCD-Module/functions/Invoke-MyOnBoarding.psm1
Normal file
193
Modules/VMware-vCD-Module/functions/Invoke-MyOnBoarding.psm1
Normal file
@@ -0,0 +1,193 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output "Overall Execution was Valid: $Valid"
|
||||
}
|
||||
}
|
||||
165
Modules/VMware-vCD-Module/functions/New-MyEdgeGateway.psm1
Normal file
165
Modules/VMware-vCD-Module/functions/New-MyEdgeGateway.psm1
Normal file
@@ -0,0 +1,165 @@
|
||||
Function New-MyEdgeGateway {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a new Edge Gateway with Default Parameters
|
||||
|
||||
.DESCRIPTION
|
||||
Creates a new Edge Gateway with Default Parameters
|
||||
|
||||
Default Parameters are:
|
||||
* HA State
|
||||
* DNS Relay
|
||||
|
||||
|
||||
.NOTES
|
||||
File Name : New-MyEdgeGateway.ps1
|
||||
Author : Markus Kraus
|
||||
Version : 1.1
|
||||
State : Ready
|
||||
|
||||
.LINK
|
||||
https://mycloudrevolution.com/
|
||||
|
||||
.EXAMPLE
|
||||
New-MyEdgeGateway -Name "TestEdge" -OrgVDCName "TestVDC" -OrgName "TestOrg" -Size compact -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 Size
|
||||
Size of the new Edge Gateway 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="Size of the new Edge Gateway as string")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[ValidateSet("compact","full")]
|
||||
[String] $Size,
|
||||
[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 = $Size
|
||||
$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
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
105
Modules/VMware-vCD-Module/functions/New-MyOrg.psm1
Normal file
105
Modules/VMware-vCD-Module/functions/New-MyOrg.psm1
Normal file
@@ -0,0 +1,105 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
89
Modules/VMware-vCD-Module/functions/New-MyOrgAdmin.psm1
Normal file
89
Modules/VMware-vCD-Module/functions/New-MyOrgAdmin.psm1
Normal file
@@ -0,0 +1,89 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
166
Modules/VMware-vCD-Module/functions/New-MyOrgNetwork.psm1
Normal file
166
Modules/VMware-vCD-Module/functions/New-MyOrgNetwork.psm1
Normal file
@@ -0,0 +1,166 @@
|
||||
Function New-MyOrgNetwork {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a new Org Network with Default Parameters
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
.NOTES
|
||||
File Name : New-MyOrgNetwork.ps1
|
||||
Author : Markus Kraus
|
||||
Version : 1.1
|
||||
State : Ready
|
||||
|
||||
.LINK
|
||||
https://mycloudrevolution.com
|
||||
|
||||
.EXAMPLE
|
||||
New-MyOrgNetwork -Name Test -OrgVdcName "Test-OrgVDC" -OrgName "Test-Org" -EdgeName "Test-OrgEdge" -SubnetMask 255.255.255.0 -Gateway 192.168.66.1 -IPRangeStart 192.168.66.100 -IPRangeEnd 192.168.66.200
|
||||
|
||||
.EXAMPLE
|
||||
New-MyOrgNetwork -Name Test -OrgVdcName "Test-OrgVDC" -OrgName "Test-Org" -EdgeName "Test-OrgEdge" -SubnetMask 255.255.255.0 -Gateway 192.168.66.1 -IPRangeStart 192.168.66.100 -IPRangeEnd 192.168.66.200 -Shared:$False
|
||||
|
||||
.EXAMPLE
|
||||
$params = @{ 'Name' = 'Test';
|
||||
'OrgVdcName'= 'Test-OrgVDC';
|
||||
'OrgName'='Test-Org';
|
||||
'EdgeName'='Test-OrgEdge';
|
||||
'SubnetMask' = '255.255.255.0';
|
||||
'Gateway' = '192.168.66.1';
|
||||
'IPRangeStart' = '192.168.66.100';
|
||||
'IPRangeEnd' = '192.168.66.200'
|
||||
}
|
||||
New-MyOrgNetwork @params -Verbose
|
||||
|
||||
.PARAMETER Name
|
||||
Name of the New Org Network as String
|
||||
|
||||
.PARAMETER OrgVDCName
|
||||
OrgVDC where the new Org Network should be created as string
|
||||
|
||||
.PARAMETER OrgName
|
||||
Org where the newOrg Networkshould be created as string
|
||||
|
||||
.PARAMETER EdgeName
|
||||
Edge Gateway Name for the new Org Network as String
|
||||
|
||||
.PARAMETER SubnetMask
|
||||
Subnet Mask of the New Org Network as IP Address
|
||||
|
||||
.PARAMETER Gateway
|
||||
Gateway of the New Org Network as IP Address
|
||||
|
||||
.PARAMETER IPRangeStart
|
||||
IP Range Start of the New Org Network as IP Address
|
||||
|
||||
.PARAMETER IPRangeEnd
|
||||
IP Range End of the New Org Network as IP Address
|
||||
|
||||
.PARAMETER Shared
|
||||
Switch for Shared OrgVDC Network
|
||||
|
||||
Default: $True
|
||||
|
||||
.PARAMETER Timeout
|
||||
Timeout for the Org Network to become Ready
|
||||
|
||||
Default: 120s
|
||||
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Name of the New Org Network as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Name,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="OrgVDC where the new Org Network should be created as string")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $OrgVdcName,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Org where the new Org Network should be created as string")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $OrgName,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Edge Gateway Name for the new Org Network as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $EdgeName,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Subnet Mask of the New Org Network as IP Address")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[IPAddress] $SubnetMask,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Gateway of the New Org Network as IP Address")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[IPAddress] $Gateway,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="IP Range Start the New Org Network as IP Address")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[IPAddress] $IPRangeStart,
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="IP Range End the New Org Network as IP Address")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[IPAddress] $IPRangeEnd,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Switch for Shared OrgVDC Network")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[Bool] $Shared = $True,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False,HelpMessage="Timeout for the Org Network to become 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!"
|
||||
}
|
||||
$orgVdcView = $orgVdc| Get-CIView
|
||||
|
||||
## Get EdgeGateway
|
||||
Write-Verbose "Get EdgeGateway"
|
||||
[Array] $edgeGateway = Search-Cloud -QueryType EdgeGateway -Name $EdgeName | Get-CIView
|
||||
if ( $edgeGateway.Count -gt 1) {
|
||||
throw "Multiple EdgeGateways found!"
|
||||
}
|
||||
elseif ( $edgeGateway.Count -lt 1) {
|
||||
throw "No EdgeGateway found!"
|
||||
}
|
||||
|
||||
## Define Org Network
|
||||
Write-Verbose "Define Org Network"
|
||||
$OrgNetwork = new-object vmware.vimautomation.cloud.views.orgvdcnetwork
|
||||
$OrgNetwork.name = $Name
|
||||
$OrgNetwork.edgegateway = $edgeGateway.id
|
||||
$OrgNetwork.isshared = $Shared
|
||||
|
||||
$OrgNetwork.configuration = new-object vmware.vimautomation.cloud.views.networkconfiguration
|
||||
$OrgNetwork.configuration.fencemode = "natRouted"
|
||||
$OrgNetwork.configuration.ipscopes = new-object vmware.vimautomation.cloud.views.ipscopes
|
||||
|
||||
$Scope = new-object vmware.vimautomation.cloud.views.ipScope
|
||||
$Scope.gateway = $Gateway
|
||||
$Scope.netmask = $SubnetMask
|
||||
|
||||
$Scope.ipranges = new-object vmware.vimautomation.cloud.views.ipranges
|
||||
$Scope.ipranges.iprange = new-object vmware.vimautomation.cloud.views.iprange
|
||||
$Scope.ipranges.iprange[0].startaddress = $IPRangeStart
|
||||
$Scope.ipranges.iprange[0].endaddress = $IPRangeEnd
|
||||
|
||||
$OrgNetwork.configuration.ipscopes.ipscope += $Scope
|
||||
|
||||
## Create Org Network
|
||||
Write-Verbose "Create Org Network"
|
||||
$CreateOrgNetwork = $orgVdcView.CreateNetwork($OrgNetwork)
|
||||
|
||||
## Wait for Org Network to become Ready
|
||||
Write-Verbose "Wait for Org Network to become Ready"
|
||||
while(!(Get-OrgVdcNetwork -Id $CreateOrgNetwork.Id -ErrorAction SilentlyContinue)){
|
||||
$i++
|
||||
Start-Sleep 5
|
||||
if($i -gt $Timeout) { Write-Error "Creating Org Network."; break}
|
||||
Write-Progress -Activity "Creating Org Network" -Status "Wait for Network to become Ready..."
|
||||
}
|
||||
Write-Progress -Activity "Creating Org Network" -Completed
|
||||
Start-Sleep 1
|
||||
|
||||
Get-OrgVdcNetwork -Id $CreateOrgNetwork.Id | Select-Object Name, OrgVdc, NetworkType, DefaultGateway, Netmask, StaticIPPool, @{ N='isShared'; E = {$_.ExtensionData.isShared} } | Format-Table -AutoSize
|
||||
|
||||
}
|
||||
}
|
||||
265
Modules/VMware-vCD-Module/functions/New-MyOrgVdc.psm1
Normal file
265
Modules/VMware-vCD-Module/functions/New-MyOrgVdc.psm1
Normal file
@@ -0,0 +1,265 @@
|
||||
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:
|
||||
* Network Quota
|
||||
* VM Quota
|
||||
* 'vCpu In Mhz'
|
||||
* Fast Provisioning
|
||||
* Thin Provisioning
|
||||
* private Catalog
|
||||
|
||||
.NOTES
|
||||
File Name : New-MyOrgVdc.ps1
|
||||
Author : Markus Kraus
|
||||
Version : 1.3
|
||||
State : Ready
|
||||
|
||||
.LINK
|
||||
https://mycloudrevolution.com/
|
||||
|
||||
.EXAMPLE
|
||||
New-MyOrgVdc -Name "TestVdc" -AllocationModel AllocationPool -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" -AllocationModel AllocationVApp -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 AllocationModel
|
||||
Allocation Model of the New Org VDC as String
|
||||
|
||||
.PARAMETER CPULimit
|
||||
CPU Limit (MHz) of the New Org VDC as String
|
||||
|
||||
Default: 0 (Unlimited)
|
||||
|
||||
Note: If AllocationModel is not AllocationVApp (Pay as you go), a limit needs to be set
|
||||
|
||||
.PARAMETER MEMLimit
|
||||
Memory Limit (MB) of the New Org VDC as String
|
||||
|
||||
Default: 0 (Unlimited)
|
||||
|
||||
Note: If AllocationModel is not AllocationVApp (Pay as you go), a limit needs to be set
|
||||
|
||||
.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="Allocation Model of the New Org VDC as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[ValidateSet("AllocationPool","AllocationVApp")]
|
||||
[String] $AllocationModel,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="CPU Limit (MHz) of the New Org VDC as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[int] $CPULimit = 0,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Memory Limit (MB) of the New Org VDC as String")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[int] $MEMLimit = 0,
|
||||
[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 = $AllocationModel
|
||||
$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 = 2000
|
||||
$adminVdc.VCpuInMhz2 = 2000
|
||||
$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 OrgVdc getting Ready after creation"
|
||||
$i = 0
|
||||
while(($orgVdc = Get-OrgVdc -Name $Name -Verbose:$false).Status -eq "NotReady"){
|
||||
$i++
|
||||
Start-Sleep 2
|
||||
if($i -gt $Timeout) { Write-Error "Creating OrgVdc Failed."; break}
|
||||
Write-Progress -Activity "Creating OrgVdc" -Status "Wait for OrgVdc to become Ready..."
|
||||
}
|
||||
Write-Progress -Activity "Creating OrgVdc" -Completed
|
||||
Start-Sleep 2
|
||||
|
||||
## Search given Storage Profile
|
||||
Write-Verbose "Search given Storage Profile"
|
||||
$Filter = "ProviderVdc==" + $OrgVdcproviderVdc.Id
|
||||
$ProVdcStorageProfile = search-cloud -QueryType ProviderVdcStorageProfile -Name $StorageProfile -Filter $Filter | 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 OrgVdc getting Ready after update"
|
||||
while(($orgVdc = Get-OrgVdc -Name $name -Verbose:$false).Status -eq "NotReady"){
|
||||
$i++
|
||||
Start-Sleep 1
|
||||
if($i -gt $Timeout) { Write-Error "Update OrgVdc Failed."; break}
|
||||
Write-Progress -Activity "Updating OrgVdc" -Status "Wait for OrgVdc to become Ready..."
|
||||
}
|
||||
Write-Progress -Activity "Updating OrgVdc" -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
|
||||
}
|
||||
}
|
||||
97
Modules/VMware.CSP/VMware.CSP.psm1
Normal file
97
Modules/VMware.CSP/VMware.CSP.psm1
Normal file
@@ -0,0 +1,97 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
Function Get-CSPAccessToken {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 07/23/2018
|
||||
Organization: VMware
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
Converts a Refresh Token from the VMware Console Services Portal
|
||||
to CSP Access Token to access CSP API
|
||||
.PARAMETER RefreshToken
|
||||
The Refresh Token from the VMware Console Services Portal
|
||||
.EXAMPLE
|
||||
Get-CSPAccessToken -RefreshToken $RefreshToken
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$true)][String]$RefreshToken
|
||||
)
|
||||
|
||||
$results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize" -Method POST -Headers @{accept='application/json'} -Body "refresh_token=$RefreshToken"
|
||||
if($results.StatusCode -ne 200) {
|
||||
Write-Host -ForegroundColor Red "Failed to retrieve Access Token, please ensure your VMC Refresh Token is valid and try again"
|
||||
break
|
||||
}
|
||||
$accessToken = ($results | ConvertFrom-Json).access_token
|
||||
Write-Host "CSP Auth Token has been successfully retrieved and saved to `$env:cspAuthToken"
|
||||
$env:cspAuthToken = $accessToken
|
||||
}
|
||||
|
||||
Function Get-CSPServices {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 07/23/2018
|
||||
Organization: VMware
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
Returns the list of CSP Services avialable for given user
|
||||
.EXAMPLE
|
||||
Get-CSPServices
|
||||
#>
|
||||
If (-Not $env:cspAuthToken) { Write-error "CSP Auth Token not found, please run Get-CSPAccessToken" } Else {
|
||||
$results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/slc/api/definitions?expand=1" -Method GET -ContentType "application/json" -UseBasicParsing -Headers @{"csp-auth-token"="$env:cspAuthToken"}
|
||||
((($results.Content) | ConvertFrom-Json).results | where {$_.visible -eq $true}).displayName
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-CSPRefreshTokenExpiry {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 01/10/2019
|
||||
Organization: VMware
|
||||
Blog: https://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
Retrieve the expiry for a given CSP Refresh Token
|
||||
.PARAMETER RefreshToken
|
||||
Retrieve the expiry for a given CSP Refresh Token
|
||||
.EXAMPLE
|
||||
Get-CSPRefreshTokenExpiry -RefreshToken $RefreshToken
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$true)][String]$RefreshToken
|
||||
)
|
||||
|
||||
$body = @{"tokenValue"="$RefreshToken"}
|
||||
$json = $body | ConvertTo-Json
|
||||
$results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/details" -Method POST -ContentType "application/json" -UseBasicParsing -Body $json
|
||||
$tokenDetails = (($results.Content) | ConvertFrom-Json)
|
||||
|
||||
$createDate = (Get-Date -Date "01/01/1970").AddMilliseconds($tokenDetails.createdAt).ToLocalTime()
|
||||
$usedDate = (Get-Date -Date "01/01/1970").AddMilliseconds($tokenDetails.lastUsedAt).ToLocalTime()
|
||||
$expiryDate = (Get-Date -Date "01/01/1970").AddMilliseconds($tokenDetails.expiresAt).ToLocalTime()
|
||||
|
||||
$tmp = [pscustomobject] @{
|
||||
LastUsedDate = $usedDate;
|
||||
CreatedDate = $createDate;
|
||||
ExpiryDate = $expiryDate;
|
||||
}
|
||||
$tmp | Format-List
|
||||
}
|
||||
128
Modules/VMware.Community.CISTag/VMware.Community.CISTag.psd1
Normal file
128
Modules/VMware.Community.CISTag/VMware.Community.CISTag.psd1
Normal file
@@ -0,0 +1,128 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
|
||||
#
|
||||
# Module manifest for module 'VMware.Community.CISTag'
|
||||
#
|
||||
# Generated by: Kyle Ruddy
|
||||
#
|
||||
# Generated on: 12/14/18
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'VMware.Community.CISTag.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.0.0'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = 'a0803efd-6017-4049-bfc9-5983a5a0c348'
|
||||
|
||||
# Author of this module
|
||||
Author = 'Kyle Ruddy'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'VMware'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = '(c) VMware. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = 'Community sourced PowerShell Module for managing vSphere Tags via the CIS Endpoint'
|
||||
|
||||
# Minimum version of the PowerShell engine required by this module
|
||||
PowerShellVersion = '4.0'
|
||||
|
||||
# Name of the PowerShell host required by this module
|
||||
# PowerShellHostName = ''
|
||||
|
||||
# Minimum version of the PowerShell host required by this module
|
||||
# PowerShellHostVersion = ''
|
||||
|
||||
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# DotNetFrameworkVersion = ''
|
||||
|
||||
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# 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, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
|
||||
FunctionsToExport = 'Get-CISTag', 'Get-CISTagCategory', 'Get-CISTagAssignment', 'New-CISTag', 'New-CISTagCategory', 'New-CISTagAssignment', 'Remove-CISTag', 'Remove-CISTagCategory', 'Remove-CISTagAssignment'
|
||||
|
||||
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
|
||||
# CmdletsToExport = '*'
|
||||
|
||||
# Variables to export from this module
|
||||
# VariablesToExport = '*'
|
||||
|
||||
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
|
||||
# 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 = ''
|
||||
|
||||
# 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 = ''
|
||||
|
||||
}
|
||||
|
||||
774
Modules/VMware.Community.CISTag/VMware.Community.CISTag.psm1
Normal file
774
Modules/VMware.Community.CISTag/VMware.Community.CISTag.psm1
Normal file
@@ -0,0 +1,774 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
function Get-CISTag {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Gathers tag information from the CIS REST API endpoint
|
||||
.DESCRIPTION
|
||||
Will provide a list of tags
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy
|
||||
.PARAMETER Name
|
||||
Tag name which should be retreived
|
||||
.PARAMETER Category
|
||||
Tag category name which should be retreived
|
||||
.PARAMETER Id
|
||||
Tag ID which should be retreived
|
||||
.EXAMPLE
|
||||
Get-CISTag
|
||||
Retreives all tag information
|
||||
.EXAMPLE
|
||||
Get-CISTag -Name tagName
|
||||
Retreives the tag information based on the specified name
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low')]
|
||||
param(
|
||||
[Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$false,Position=1,ValueFromPipelineByPropertyName=$true)]
|
||||
[String]$Category,
|
||||
[Parameter(Mandatory=$false,Position=2,ValueFromPipelineByPropertyName=$true)]
|
||||
[String]$Id
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
|
||||
$tagSvc = Get-CisService -Name com.vmware.cis.tagging.tag
|
||||
if ($PSBoundParameters.ContainsKey("Id")) {
|
||||
$tagOutput = $tagSvc.get($Id)
|
||||
} else {
|
||||
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
|
||||
[Boolean]$vCenterConn = $true
|
||||
$vCTagList = Get-Tag
|
||||
} else {
|
||||
$tagArray = @()
|
||||
$tagIdList = $tagSvc.list() | Select-Object -ExpandProperty Value
|
||||
[int]$counter = 1
|
||||
foreach ($t in $tagIdList) {
|
||||
$tagArray += $tagSvc.get($t)
|
||||
$counter++
|
||||
if ($counter -gt 200) {Start-Sleep -Milliseconds 1; $counter = 1}
|
||||
}
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey("Name")) {
|
||||
if ($vCenterConn){
|
||||
$tagOutput = $vCTagList | Where-Object {$_.Name -eq $Name}
|
||||
} else {$tagOutput = $tagArray | Where-Object {$_.Name -eq $Name}}
|
||||
} elseif ($PSBoundParameters.ContainsKey("Category")) {
|
||||
if ($vCenterConn){
|
||||
$tagOutput = $vCTagList | Where-Object {$_.Category -eq $Category}
|
||||
} else {
|
||||
$tagCatid = Get-CISTagCategory -Name $Category | Select-Object -ExpandProperty Id
|
||||
$tagIdList = $tagSvc.list_tags_for_category($tagCatid)
|
||||
$tagArray2 = @()
|
||||
foreach ($t in $tagIdList) {
|
||||
$tagArray2 += $tagSvc.get($t)
|
||||
}
|
||||
$tagOutput = $tagArray2
|
||||
}
|
||||
} else {
|
||||
if ($vCenterConn){$tagOutput = $vCTagList}
|
||||
else {$tagOutput = $tagArray}
|
||||
}
|
||||
}
|
||||
$tagOutput | Select-Object Id, Name, Description
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function New-CISTag {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a new tag from the CIS REST API endpoint
|
||||
.DESCRIPTION
|
||||
Will create a new tag
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy
|
||||
.PARAMETER Name
|
||||
Tag name which should be created
|
||||
.PARAMETER Category
|
||||
Category name where the new tag should be associated
|
||||
.PARAMETER Description
|
||||
Description for the new tag
|
||||
.PARAMETER CategoryID
|
||||
Category ID where the new tag should be associated
|
||||
.EXAMPLE
|
||||
New-CISTag -Name tagName -Category categoryName -Description "Tag Descrition"
|
||||
Creates a new tag based on the specified name
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Medium')]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,Position=0)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$false,Position=1)]
|
||||
[String]$Category,
|
||||
[Parameter(Mandatory=$false,Position=2)]
|
||||
[String]$Description,
|
||||
[Parameter(Mandatory=$false,Position=3)]
|
||||
[String]$CategoryID
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
|
||||
$tagSvc = Get-CisService -Name com.vmware.cis.tagging.tag
|
||||
$tagCreateHelper = $tagSvc.Help.create.create_spec.Create()
|
||||
$tagCreateHelper.name = $Name
|
||||
if ($PSBoundParameters.ContainsKey("Category")) {
|
||||
$tagCreateHelper.category_id = Get-CISTagCategory -Name $Category | Select-Object -ExpandProperty Id
|
||||
} elseif ($PSBoundParameters.ContainsKey("CategoryId")) {
|
||||
$tagCreateHelper.category_id = $CategoryID
|
||||
} else {Write-Warning "No Category input found. Add a Category name or ID."; break}
|
||||
if ($PSBoundParameters.ContainsKey("Description")) {
|
||||
$tagCreateHelper.description = $Description
|
||||
} else {
|
||||
$tagCreateHelper.description = ""
|
||||
}
|
||||
$tagNewId = $tagSvc.create($tagCreateHelper)
|
||||
Get-CISTag -Id $tagNewId
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function Remove-CISTag {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Removes a tag from the CIS REST API endpoint
|
||||
.DESCRIPTION
|
||||
Will delete a new tag
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy
|
||||
.PARAMETER Name
|
||||
Tag name which should be removed
|
||||
.PARAMETER ID
|
||||
Tag ID which should be removed
|
||||
.EXAMPLE
|
||||
Remove-CISTag -Name tagName
|
||||
Removes a new tag based on the specified name
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
|
||||
param(
|
||||
[Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$false,Position=1,ValueFromPipelineByPropertyName=$true)]
|
||||
[String]$ID
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
|
||||
$tagSvc = Get-CisService -Name com.vmware.cis.tagging.tag
|
||||
if ($ID) {
|
||||
$tagSvc.delete($ID)
|
||||
} else {
|
||||
$tagId = Get-CISTag -Name $Name | select -ExpandProperty Id
|
||||
if ($tagId) {$tagSvc.delete($tagId)}
|
||||
else {Write-Warning "No valid tag found."}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-CISTagCategory {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Gathers tag category information from the CIS REST API endpoint
|
||||
.DESCRIPTION
|
||||
Will provide a list of tag categories
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy
|
||||
.PARAMETER Name
|
||||
Tag category name which should be retreived
|
||||
.PARAMETER Id
|
||||
Tag category ID which should be retreived
|
||||
.EXAMPLE
|
||||
Get-CISTagCategory
|
||||
Retreives all tag category information
|
||||
.EXAMPLE
|
||||
Get-CISTagCategory -Name tagCategoryName
|
||||
Retreives the tag category information based on the specified name
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low')]
|
||||
param(
|
||||
[Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$false,Position=2,ValueFromPipelineByPropertyName=$true)]
|
||||
[String]$Id
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
|
||||
$tagCatSvc = Get-CisService -Name com.vmware.cis.tagging.category
|
||||
if ($PSBoundParameters.ContainsKey("Id")) {
|
||||
$tagCatOutput = $tagCatSvc.get($Id)
|
||||
} else {
|
||||
$tagCatArray = @()
|
||||
$tagCatIdList = $tagCatSvc.list() | Select-Object -ExpandProperty Value
|
||||
foreach ($tc in $tagCatIdList) {
|
||||
$tagCatArray += $tagCatSvc.get($tc)
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey("Name")) {
|
||||
$tagCatOutput = $tagCatArray | Where-Object {$_.Name -eq $Name}
|
||||
} else {
|
||||
$tagCatOutput = $tagCatArray
|
||||
}
|
||||
}
|
||||
$tagCatOutput | Select-Object Id, Name, Description, Cardinality
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function New-CISTagCategory {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a new tag category from the CIS REST API endpoint
|
||||
.DESCRIPTION
|
||||
Will create a new tag category
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy
|
||||
.PARAMETER Name
|
||||
Tag category name which should be created
|
||||
.PARAMETER Description
|
||||
Tag category ID which should be retreived
|
||||
.PARAMETER Cardinality
|
||||
Tag category ID which should be retreived
|
||||
.PARAMETER AssociableTypes
|
||||
Tag category ID which should be retreived
|
||||
.EXAMPLE
|
||||
New-CISTagCategory -Name NewTagCategoryName -Description "New Tag Category Description" -Cardinality "Single" -AssociableTypes
|
||||
Creates a new tag category with the specified information
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Medium')]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,Position=0)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$false,Position=1)]
|
||||
[String]$Description,
|
||||
[Parameter(Mandatory=$false,Position=2)]
|
||||
[ValidateSet("SINGLE","MULTIPLE")]
|
||||
[String]$Cardinality = "SINGLE",
|
||||
[Parameter(Mandatory=$false,Position=3)]
|
||||
[ValidateSet("All", "Cluster", "Datacenter", "Datastore", "DatastoreCluster", "DistributedPortGroup", "DistributedSwitch", "Folder", "ResourcePool", "VApp", "VirtualPortGroup", "VirtualMachine", "VMHost")]
|
||||
[String]$AssociableTypes = "All"
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
|
||||
$tagCatSvc = Get-CisService -Name com.vmware.cis.tagging.category
|
||||
$tagCatCreateHelper = $tagCatSvc.Help.create.create_spec.Create()
|
||||
$tagCatCreateHelper.name = $Name
|
||||
if ($PSBoundParameters.ContainsKey("Description")) {
|
||||
$tagCatCreateHelper.description = $Description
|
||||
} else {$tagCatCreateHelper.description = ""}
|
||||
$tagCatCreateHelper.cardinality = $Cardinality
|
||||
$tagCatCreateAssocTypeHelper = $tagCatSvc.help.create.create_spec.associable_types.create()
|
||||
$tagCatCreateAssocTypeHelper.Add($AssociableTypes)
|
||||
$tagCatCreateHelper.associable_types = $tagCatCreateAssocTypeHelper
|
||||
$tagCatNewId = $tagCatSvc.create($tagCatCreateHelper)
|
||||
Get-CISTagCategory -Id $tagCatNewId
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function Remove-CISTagCategory {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Removes tag category information from the CIS REST API endpoint
|
||||
.DESCRIPTION
|
||||
Will remove a tag category
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy
|
||||
.PARAMETER Name
|
||||
Tag category name which should be removed
|
||||
.PARAMETER Id
|
||||
Tag category ID which should be removed
|
||||
.EXAMPLE
|
||||
Remove-CISTagCategory -Name tagCategoryName
|
||||
Removes the tag category information based on the specified name
|
||||
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
|
||||
param(
|
||||
[Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$false,Position=2,ValueFromPipelineByPropertyName=$true)]
|
||||
[String]$Id
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
|
||||
$tagCatSvc = Get-CisService -Name com.vmware.cis.tagging.category
|
||||
if ($PSBoundParameters.ContainsKey("Id")) {
|
||||
$tagCatSvc.delete($Id)
|
||||
} elseif ($PSBoundParameters.ContainsKey("Name")) {
|
||||
$tagCatId = Get-CISTagCategory -Name $Name | Select-Object -ExpandProperty Id
|
||||
$tagCatSvc.delete($tagCatId)
|
||||
} else {Write-Warning "No tag category found."}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-CISTagAssignment {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Displays a list of the tag assignments from the CIS REST API endpoint
|
||||
.DESCRIPTION
|
||||
Will provide a list of the tag assignments
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy
|
||||
.PARAMETER Category
|
||||
Tag category name which should be referenced
|
||||
.PARAMETER Entity
|
||||
Object name which should be retreived
|
||||
.PARAMETER ObjectId
|
||||
Object ID which should be retreived
|
||||
.EXAMPLE
|
||||
Get-CISTagAssignment
|
||||
Retreives all tag assignment information
|
||||
.EXAMPLE
|
||||
Get-CISTagAssignment -Entity VMName
|
||||
Retreives all tag assignments for the VM name
|
||||
.EXAMPLE
|
||||
Get-CISTagAssignment -ObjectId 'vm-11'
|
||||
Retreives all tag assignments for the VM object
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low')]
|
||||
param(
|
||||
[Parameter(Mandatory=$false,Position=0)]
|
||||
[String]$Category,
|
||||
[Parameter(Mandatory=$false,Position=1)]
|
||||
[String]$Entity,
|
||||
[Parameter(Mandatory=$false,Position=2,ValueFromPipelineByPropertyName=$true)]
|
||||
[String]$ObjectId
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
|
||||
$tagOutput = @()
|
||||
[Boolean]$vCenterConn = $false
|
||||
$tagAssocSvc = Get-CisService -Name com.vmware.cis.tagging.tag_association
|
||||
if ($PSBoundParameters.ContainsKey("ObjectId")) {
|
||||
if ($ObjectId.split('-')[0] -eq 'vm') {
|
||||
$objType = "VirtualMachine"
|
||||
} elseif ($ObjectId.Split('-')[0] -eq 'datastore') {
|
||||
$objType = 'Datastore'
|
||||
} else {Write-Warning 'Only VirtualMachine and Datastore types currently supported.'; break}
|
||||
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
|
||||
$objObject.id = $ObjectId
|
||||
$objObject.type = $objType
|
||||
$tagIdOutput = $tagAssocSvc.list_attached_tags($objObject)
|
||||
} elseif ($PSBoundParameters.ContainsKey("Entity")) {
|
||||
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
|
||||
[Boolean]$vCenterConn = $true
|
||||
$viObject = (Get-Inventory -Name $Entity).ExtensionData.MoRef
|
||||
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
|
||||
$objObject.id = $viObject.Value
|
||||
$objObject.type = $viObject.type
|
||||
} else {
|
||||
$vmSvc = Get-CisService -Name com.vmware.vcenter.vm
|
||||
$filterVmNameObj = $vmsvc.help.list.filter.create()
|
||||
$filterVmNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
|
||||
if ($objId) {$objType = "VirtualMachine"}
|
||||
else {
|
||||
$dsSvc = Get-CisService com.vmware.vcenter.datastore
|
||||
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
|
||||
$filterDsNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
|
||||
if ($objId) {$objType = "Datastore"}
|
||||
else {Write-Warning "No entities found."; break}
|
||||
}
|
||||
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
|
||||
$objObject.id = $objId
|
||||
$objObject.type = $objType
|
||||
}
|
||||
$tagIdOutput = $tagAssocSvc.list_attached_tags($objObject)
|
||||
} else {
|
||||
$tagSvc = Get-CisService -Name com.vmware.cis.tagging.tag
|
||||
$tagIdOutput = @()
|
||||
$tagCategories = Get-CISTagCategory | Sort-Object -Property Name
|
||||
if ($Category) {
|
||||
$tagCatId = $tagCategories | Where-Object {$_.Name -eq $Category} | Select-Object -ExpandProperty Id
|
||||
$tagIdOutput += $tagSvc.list_tags_for_category($tagCatId)
|
||||
} else {
|
||||
foreach ($tagCat in $tagCategories) {
|
||||
$tagIdOutput += $tagSvc.list_tags_for_category($tagCat.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
$tagReference = Get-CISTag
|
||||
|
||||
if ($Entity -or $ObjectId) {
|
||||
foreach ($tagId in $tagIdOutput) {
|
||||
$tagAttObj = @()
|
||||
if ($Entity) {
|
||||
$tagAttObj += $tagAssocSvc.list_attached_objects($tagId) | Where-Object {$_.type -eq $viObject.type -and $_.id -eq $viObject.Value}
|
||||
} else {
|
||||
$tagAttObj += $tagAssocSvc.list_attached_objects($tagId) | Where-Object {$_.id -eq $ObjectId}
|
||||
}
|
||||
foreach ($obj in $tagAttObj) {
|
||||
if ($obj.type -eq "VirtualMachine") {
|
||||
if (-Not $vmSvc) {$vmSvc = Get-CisService -Name com.vmware.vcenter.vm}
|
||||
$filterVmObj = $vmsvc.help.list.filter.create()
|
||||
$filterVmObj.vms.add($obj.Id) | Out-Null
|
||||
$objName = $vmSvc.list($filterVmObj) | Select-Object -ExpandProperty Name
|
||||
} elseif ($obj.type -eq "Datastore") {
|
||||
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
|
||||
$filterDsObj = $dsSvc.help.list.filter.create()
|
||||
$filterDsObj.datastores.add($obj.Id) | Out-Null
|
||||
$objName = $dsSvc.list($filterDsObj) | Select-Object -ExpandProperty Name
|
||||
} else {$objName = 'Object Not Found'}
|
||||
$tempObject = "" | Select-Object Tag, Entity
|
||||
$tempObject.Tag = $tagReference | Where-Object {$_.id -eq $tagId} | Select-Object -ExpandProperty Name
|
||||
$tempObject.Entity = $objName
|
||||
$tagOutput += $tempObject
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($tagId in $tagIdOutput) {
|
||||
$tagAttObj = @()
|
||||
$tagAttObj += $tagAssocSvc.list_attached_objects($tagId)
|
||||
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
|
||||
[Boolean]$vCenterConn = $true
|
||||
} elseif ($tagAttObj.Type -contains "VirtualMachine") {
|
||||
if (-Not $vmSvc) {$vmSvc = Get-CisService -Name com.vmware.vcenter.vm}
|
||||
} elseif ($tagAttObj.Type -contains "Datastore") {
|
||||
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
|
||||
}
|
||||
foreach ($obj in $tagAttObj) {
|
||||
if ($vCenterConn) {
|
||||
$newViObj = New-Object -TypeName VMware.Vim.ManagedObjectReference
|
||||
$newViObj.Type = $obj.type
|
||||
$newViObj.Value = $obj.id
|
||||
$objName = Get-View -Id $newViObj -Property Name | Select-Object -ExpandProperty Name
|
||||
} elseif ($obj.type -eq "VirtualMachine") {
|
||||
$filterVmObj = $vmsvc.help.list.filter.create()
|
||||
$filterVmObj.vms.add($obj.Id) | Out-Null
|
||||
$objName = $vmSvc.list($filterVmObj) | Select-Object -ExpandProperty Name
|
||||
} elseif ($obj.type -eq "Datastore") {
|
||||
$filterDsObj = $dsSvc.help.list.filter.create()
|
||||
$filterDsObj.datastores.add($obj.Id) | Out-Null
|
||||
$objName = $dsSvc.list($filterDsObj) | Select-Object -ExpandProperty Name
|
||||
} else {$objName = 'Object Not Found'}
|
||||
$tempObject = "" | Select-Object Tag, Entity
|
||||
$tempObject.Tag = $tagReference | Where-Object {$_.id -eq $tagId} | Select-Object -ExpandProperty Name
|
||||
$tempObject.Entity = $objName
|
||||
$tagOutput += $tempObject
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tagOutput
|
||||
}
|
||||
}
|
||||
|
||||
function New-CISTagAssignment {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates new tag assignments from the CIS REST API endpoint
|
||||
.DESCRIPTION
|
||||
Will create new tag assignments
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy
|
||||
.PARAMETER Tag
|
||||
Tag name which should be referenced
|
||||
.PARAMETER Entity
|
||||
Object name which should be retreived
|
||||
.PARAMETER TagId
|
||||
Tag ID/s which should be referenced
|
||||
.PARAMETER ObjectId
|
||||
Object ID which/s should be retreived
|
||||
.EXAMPLE
|
||||
New-CISTagAssignment -Tag TagName -Entity VMName
|
||||
Creates a tag assignment between the Tag name and the VM name
|
||||
.EXAMPLE
|
||||
New-CISTagAssignment -TagId $tagId -ObjectId 'vm-11'
|
||||
Creates a tag assignment between the Tag ID and the Object ID
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Medium')]
|
||||
param(
|
||||
[Parameter(Mandatory=$false,Position=0)]
|
||||
$Tag,
|
||||
[Parameter(Mandatory=$false,Position=1)]
|
||||
$Entity,
|
||||
[Parameter(Mandatory=$false,Position=2)]
|
||||
$TagId,
|
||||
[Parameter(Mandatory=$false,Position=3)]
|
||||
$ObjectId
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
|
||||
$tagAssocSvc = Get-CisService -Name com.vmware.cis.tagging.tag_association
|
||||
if ($PSBoundParameters.ContainsKey("Tag") -and $PSBoundParameters.ContainsKey("Entity")) {
|
||||
if ($Tag -is [array] -and $Entity -isnot [array]) {
|
||||
$tagIdList = $tagAssocSvc.help.attach_multiple_tags_to_object.tag_ids.create()
|
||||
foreach ($t in $Tag) {
|
||||
$tempId = Get-CISTag -Name $t | Select-Object -ExpandProperty Id
|
||||
$tagIdList.add($tempId) | Out-Null
|
||||
}
|
||||
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
|
||||
$viObject = (Get-Inventory -Name $Entity).ExtensionData.MoRef
|
||||
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
|
||||
$objObject.id = $viObject.Value
|
||||
$objObject.type = $viObject.type
|
||||
} else {
|
||||
if (-Not $vmSvc) {$vmSvc = Get-CisService -Name com.vmware.vcenter.vm}
|
||||
$filterVmNameObj = $vmsvc.help.list.filter.create()
|
||||
$filterVmNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
|
||||
if ($objId) {$objType = "VirtualMachine"}
|
||||
else {
|
||||
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
|
||||
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
|
||||
$filterDsNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
|
||||
if ($objId) {$objType = "Datastore"}
|
||||
else {Write-Warning "No entities found."; break}
|
||||
}
|
||||
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
|
||||
$objObject.id = $objId
|
||||
$objObject.type = $objType
|
||||
}
|
||||
$tagAssocSvc.attach_multiple_tags_to_object($objObject,$tagIdList) | Out-Null
|
||||
} elseif ($Tag -isnot [array] -and $Entity -is [array]) {
|
||||
$tagId = Get-CISTag -Name $Tag | Select-Object -ExpandProperty Id
|
||||
$objList = $tagAssocSvc.help.attach_tag_to_multiple_objects.object_ids.create()
|
||||
foreach ($e in $Entity) {
|
||||
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
|
||||
$viObject = (Get-Inventory -Name $e).ExtensionData.MoRef
|
||||
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
|
||||
$objObject.id = $viObject.Value
|
||||
$objObject.type = $viObject.type
|
||||
} else {
|
||||
if (-Not $vmSvc) {$vmSvc = Get-CisService -Name com.vmware.vcenter.vm}
|
||||
$filterVmNameObj = $vmsvc.help.list.filter.create()
|
||||
$filterVmNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
|
||||
if ($objId) {$objType = "VirtualMachine"}
|
||||
else {
|
||||
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
|
||||
$filterDsObj = $dsSvc.help.list.filter.create()
|
||||
$filterDsObj.datastores.add($obj.Id) | Out-Null
|
||||
$objId = $dsSvc.list($filterDsObj) | Select-Object -ExpandProperty Datastore
|
||||
if ($objId) {$objType = "Datastore"}
|
||||
else {Write-Warning "No entities found."; break}
|
||||
}
|
||||
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
|
||||
$objObject.id = $objId
|
||||
$objObject.type = $objType
|
||||
}
|
||||
$objList.add($objObject) | Out-Null
|
||||
}
|
||||
$tagAssocSvc.attach_tag_to_multiple_objects($TagId,$objList) | Out-Null
|
||||
} elseif ($Tag -isnot [array] -and $Entity -isnot [array]) {
|
||||
$tagId = Get-CISTag -Name $Tag | Select-Object -ExpandProperty Id
|
||||
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
|
||||
$viObject = (Get-Inventory -Name $Entity).ExtensionData.MoRef
|
||||
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
|
||||
$objObject.id = $viObject.Value
|
||||
$objObject.type = $viObject.type
|
||||
} else {
|
||||
if (-Not $vmSvc) {$vmSvc = Get-CisService -Name com.vmware.vcenter.vm}
|
||||
$filterVmNameObj = $vmsvc.help.list.filter.create()
|
||||
$filterVmNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
|
||||
if ($objId) {$objType = "VirtualMachine"}
|
||||
else {
|
||||
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
|
||||
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
|
||||
$filterDsNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
|
||||
if ($objId) {$objType = "Datastore"}
|
||||
else {Write-Warning "No entities found."; break}
|
||||
}
|
||||
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
|
||||
$objObject.id = $objId
|
||||
$objObject.type = $objType
|
||||
}
|
||||
$tagAssocSvc.attach($TagId,$objObject) | Out-Null
|
||||
}
|
||||
} elseif ($PSBoundParameters.ContainsKey("TagId") -and $PSBoundParameters.ContainsKey("ObjectId")) {
|
||||
if ($ObjectId.split('-')[0] -eq 'vm') {
|
||||
$objType = "VirtualMachine"
|
||||
} elseif ($ObjectId.Split('-')[0] -eq 'datastore') {
|
||||
$objType = 'Datastore'
|
||||
} else {Write-Warning 'Only VirtualMachine and Datastore types currently supported.'; break}
|
||||
if ($TagId -is [array] -and $ObjectId -isnot [array]) {
|
||||
$objObject = $tagAssocSvc.help.attach_multiple_tags_to_object.object_id.create()
|
||||
$objObject.id = $ObjectId
|
||||
$objObject.type = $objType
|
||||
$tagIdList = $tagAssocSvc.help.attach_multiple_tags_to_object.tag_ids.create()
|
||||
foreach ($tId in $TagId) {
|
||||
$tagIdList.add($tId) | Out-Null
|
||||
}
|
||||
$tagAssocSvc.attach_multiple_tags_to_object($objObject,$tagIdList) | Out-Null
|
||||
} elseif ($TagId -isnot [array] -and $ObjectId -is [array]) {
|
||||
$objList = $tagAssocSvc.help.attach_tag_to_multiple_objects.object_ids.create()
|
||||
foreach ($obj in $ObjectId) {
|
||||
$objObject = $tagAssocSvc.help.attach_tag_to_multiple_objects.object_ids.element.create()
|
||||
$objObject.id = $obj
|
||||
$objObject.type = $objType
|
||||
$objList.add($objObject) | Out-Null
|
||||
}
|
||||
$tagAssocSvc.attach_tag_to_multiple_objects($TagId,$objList) | Out-Null
|
||||
} elseif ($TagId -isnot [array] -and $ObjectId -isnot [array]) {
|
||||
$objObject = $tagAssocSvc.help.attach.object_id.create()
|
||||
$objObject.id = $ObjectId
|
||||
$objObject.type = $objType
|
||||
$tagAssocSvc.attach($TagId,$objObject) | Out-Null
|
||||
}
|
||||
|
||||
} else {Write-Output "Multiple tags with multiple objects are not a supported call."}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function Remove-CISTagAssignment {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Removes a tag assignment from the CIS REST API endpoint
|
||||
.DESCRIPTION
|
||||
Will remove provided tag assignments
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy
|
||||
.PARAMETER Tag
|
||||
Tag name which should be removed
|
||||
.PARAMETER Entity
|
||||
Object name which should be removed
|
||||
.PARAMETER TagId
|
||||
Tag ID/s which should be removed
|
||||
.PARAMETER ObjectId
|
||||
Object ID which/s should be removed
|
||||
.EXAMPLE
|
||||
Remove-CISTagAssignment -TagId $tagId -ObjectId 'vm-11'
|
||||
Removes the tag assignment between the Tag ID and the Object ID
|
||||
.EXAMPLE
|
||||
Remove-CISTagAssignment -Tag TagName -Entity VMName
|
||||
Removes the tag assignment between the Tag name and the Entity name
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
|
||||
param(
|
||||
[Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
$Tag,
|
||||
[Parameter(Mandatory=$false,Position=1,ValueFromPipelineByPropertyName=$true)]
|
||||
$Entity,
|
||||
[Parameter(Mandatory=$false,Position=2)]
|
||||
$TagId,
|
||||
[Parameter(Mandatory=$false,Position=3)]
|
||||
$ObjectId
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
|
||||
$tagAssocSvc = Get-CisService -Name com.vmware.cis.tagging.tag_association
|
||||
if ($PSBoundParameters.ContainsKey("Tag") -and $PSBoundParameters.ContainsKey("Entity")) {
|
||||
if ($Tag -is [array] -and $Entity -isnot [array]) {
|
||||
$tagIdList = $tagAssocSvc.help.detach_multiple_tags_from_object.tag_ids.create()
|
||||
foreach ($t in $Tag) {
|
||||
$tempId = Get-CISTag -Name $t | Select-Object -ExpandProperty Id
|
||||
$tagIdList.add($tempId) | Out-Null
|
||||
}
|
||||
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
|
||||
$viObject = (Get-Inventory -Name $Entity).ExtensionData.MoRef
|
||||
$objObject = $tagAssocSvc.help.detach_multiple_tags_from_object.object_id.create()
|
||||
$objObject.id = $viObject.Value
|
||||
$objObject.type = $viObject.type
|
||||
} else {
|
||||
$vmSvc = Get-CisService -Name com.vmware.vcenter.vm
|
||||
$filterVmNameObj = $vmsvc.help.list.filter.create()
|
||||
$filterVmNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
|
||||
if ($objId) {$objType = "VirtualMachine"}
|
||||
else {
|
||||
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
|
||||
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
|
||||
$filterDsNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
|
||||
if ($objId) {$objType = "Datastore"}
|
||||
else {Write-Warning "No entities found."; break}
|
||||
}
|
||||
$objObject = $tagAssocSvc.help.detach_multiple_tags_from_object.object_id.create()
|
||||
$objObject.id = $objId
|
||||
$objObject.type = $objType
|
||||
}
|
||||
$tagAssocSvc.detach_multiple_tags_from_object($objObject,$tagIdList) | Out-Null
|
||||
} elseif ($Tag -isnot [array] -and $Entity -is [array]) {
|
||||
$tagId = Get-CISTag -Name $Tag | Select-Object -ExpandProperty Id
|
||||
$objList = $tagAssocSvc.help.detach_tag_from_multiple_objects.object_ids.create()
|
||||
foreach ($e in $Entity) {
|
||||
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
|
||||
$viObject = (Get-Inventory -Name $e).ExtensionData.MoRef
|
||||
$objObject = $tagAssocSvc.help.detach_tag_from_multiple_objects.object_ids.element.create()
|
||||
$objObject.id = $viObject.Value
|
||||
$objObject.type = $viObject.type
|
||||
} else {
|
||||
$vmSvc = Get-CisService -Name com.vmware.vcenter.vm
|
||||
$filterVmNameObj = $vmsvc.help.list.filter.create()
|
||||
$filterVmNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
|
||||
if ($objId) {$objType = "VirtualMachine"}
|
||||
else {
|
||||
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
|
||||
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
|
||||
$filterDsNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
|
||||
if ($objId) {$objType = "Datastore"}
|
||||
else {Write-Warning "No entities found."; break}
|
||||
}
|
||||
$objObject = $tagAssocSvc.help.detach_tag_from_multiple_objects.object_ids.element.create()
|
||||
$objObject.id = $objId
|
||||
$objObject.type = $objType
|
||||
}
|
||||
$objList.add($objObject) | Out-Null
|
||||
}
|
||||
$tagAssocSvc.detach_tag_from_multiple_objects($TagId,$objList) | Out-Null
|
||||
} elseif ($Tag -isnot [array] -and $Entity -isnot [array]) {
|
||||
$tagId = Get-CISTag -Name $Tag | Select-Object -ExpandProperty Id
|
||||
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
|
||||
$viObject = (Get-Inventory -Name $Entity).ExtensionData.MoRef
|
||||
$objObject = $tagAssocSvc.help.detach.object_id.create()
|
||||
$objObject.id = $viObject.Value
|
||||
$objObject.type = $viObject.type
|
||||
} else {
|
||||
$vmSvc = Get-CisService -Name com.vmware.vcenter.vm
|
||||
$filterVmNameObj = $vmsvc.help.list.filter.create()
|
||||
$filterVmNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
|
||||
if ($objId) {$objType = "VirtualMachine"}
|
||||
else {
|
||||
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
|
||||
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
|
||||
$filterDsNameObj.names.add($Entity) | Out-Null
|
||||
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
|
||||
if ($objId) {$objType = "Datastore"}
|
||||
else {Write-Warning "No entities found."; break}
|
||||
}
|
||||
$objObject = $tagAssocSvc.help.detach.object_id.create()
|
||||
$objObject.id = $objId
|
||||
$objObject.type = $objType
|
||||
}
|
||||
$tagAssocSvc.detach($TagId,$objObject) | Out-Null
|
||||
}
|
||||
} elseif ($PSBoundParameters.ContainsKey("TagId") -and $PSBoundParameters.ContainsKey("ObjectId")) {
|
||||
if ($ObjectId.split('-')[0] -eq 'vm') {
|
||||
$objType = "VirtualMachine"
|
||||
} elseif ($ObjectId.Split('-')[0] -eq 'datastore') {
|
||||
$objType = 'Datastore'
|
||||
}else {Write-Warning 'Only VirtualMachine types currently supported.'; break}
|
||||
if ($TagId -is [array] -and $ObjectId -isnot [array]) {
|
||||
$objObject = $tagAssocSvc.help.detach_multiple_tags_from_object.object_id.create()
|
||||
$objObject.id = $ObjectId
|
||||
$objObject.type = $objType
|
||||
$tagIdList = $tagAssocSvc.help.detach_multiple_tags_from_object.tag_ids.create()
|
||||
foreach ($tId in $TagId) {
|
||||
$tagIdList.add($tId) | Out-Null
|
||||
}
|
||||
$tagAssocSvc.detach_multiple_tags_from_object($objObject,$tagIdList) | Out-Null
|
||||
} elseif ($TagId -isnot [array] -and $ObjectId -is [array]) {
|
||||
$objList = $tagAssocSvc.help.detach_tag_from_multiple_objects.object_ids.create()
|
||||
foreach ($obj in $ObjectId) {
|
||||
$objObject = $tagAssocSvc.help.detach_tag_from_multiple_objects.object_ids.element.create()
|
||||
$objObject.id = $obj
|
||||
$objObject.type = $objType
|
||||
$objList.add($objObject) | Out-Null
|
||||
}
|
||||
$tagAssocSvc.detach_tag_from_multiple_objects($TagId,$objList) | Out-Null
|
||||
} elseif ($TagId -isnot [array] -and $ObjectId -isnot [array]) {
|
||||
$objObject = $tagAssocSvc.help.detach.object_id.create()
|
||||
$objObject.id = $ObjectId
|
||||
$objObject.type = $objType
|
||||
$tagAssocSvc.detach($TagId,$objObject) | Out-Null
|
||||
}
|
||||
} else {Write-Output "Multiple tags with multiple objects are not a supported call."}
|
||||
|
||||
}
|
||||
}
|
||||
BIN
Modules/VMware.DRaaS/VMware.DRaaS.psd1
Executable file
BIN
Modules/VMware.DRaaS/VMware.DRaaS.psd1
Executable file
Binary file not shown.
260
Modules/VMware.DRaaS/VMware.DRaaS.psm1
Normal file
260
Modules/VMware.DRaaS/VMware.DRaaS.psm1
Normal file
@@ -0,0 +1,260 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
Function Connect-DRaas {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 05/23/2019
|
||||
Organization: VMware
|
||||
Blog: http://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
This cmdlet creates $global:draasConnection object containing the DRaaS URL along with CSP Token Header
|
||||
.DESCRIPTION
|
||||
This cmdlet creates $global:draasConnection object containing the DRaaS URL along with CSP Token Header
|
||||
.EXAMPLE
|
||||
Connect-DRaaS -RefreshToken $RefreshToken -OrgName $OrgName -SDDCName $SDDCName
|
||||
.NOTES
|
||||
You must be logged into VMC using Connect-VmcServer cmdlet
|
||||
#>
|
||||
Param (
|
||||
[Parameter(Mandatory=$true)][String]$RefreshToken,
|
||||
[Parameter(Mandatory=$true)][String]$OrgName,
|
||||
[Parameter(Mandatory=$true)][String]$SDDCName
|
||||
)
|
||||
|
||||
If (-Not $global:DefaultVMCServers.IsConnected) { Write-error "No valid VMC Connection found, please use the Connect-VMC to connect"; break } Else {
|
||||
$sddcService = Get-VmcService "com.vmware.vmc.orgs.sddcs"
|
||||
$orgId = (Get-VMCOrg -Name $OrgName).Id
|
||||
$sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id
|
||||
$sddc = $sddcService.get($orgId,$sddcId)
|
||||
|
||||
}
|
||||
|
||||
$results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize" -Method POST -Headers @{accept='application/json'} -Body "refresh_token=$RefreshToken"
|
||||
if($results.StatusCode -ne 200) {
|
||||
Write-Host -ForegroundColor Red "Failed to retrieve Access Token, please ensure your VMC Refresh Token is valid and try again"
|
||||
break
|
||||
}
|
||||
$accessToken = ($results | ConvertFrom-Json).access_token
|
||||
|
||||
$headers = @{
|
||||
"csp-auth-token"="$accessToken"
|
||||
"Content-Type"="application/json"
|
||||
"Accept"="application/json"
|
||||
}
|
||||
$global:draasConnection = new-object PSObject -Property @{
|
||||
'Server' = "https://vmc.vmware.com/vmc/draas/api/orgs/$orgId/sddcs/$sddcId/site-recovery"
|
||||
'headers' = $headers
|
||||
}
|
||||
$global:draasConnection
|
||||
}
|
||||
|
||||
Function Get-DRaas {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 05/23/2019
|
||||
Organization: VMware
|
||||
Blog: http://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Returns information about DRaaS configuration for a given SDDC
|
||||
.DESCRIPTION
|
||||
This cmdlet returns information about DRaaS configuration for a given SDDC. Can be used to monitor both activate and deactivate operations.
|
||||
.EXAMPLE
|
||||
Get-DRaas
|
||||
#>
|
||||
Param (
|
||||
[Switch]$Troubleshoot
|
||||
)
|
||||
|
||||
If (-Not $global:draasConnection) { Write-error "No DRaaS Connection found, please use Connect-DRaaS" } Else {
|
||||
$method = "GET"
|
||||
$draasUrl = $global:draasConnection.Server
|
||||
$draasVersionUrl = $global:draasConnection.Server + "/versions"
|
||||
|
||||
if($Troubleshoot) {
|
||||
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasUrl`n"
|
||||
}
|
||||
|
||||
try {
|
||||
if($PSVersionTable.PSEdition -eq "Core") {
|
||||
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck
|
||||
} else {
|
||||
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers
|
||||
}
|
||||
} catch {
|
||||
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
|
||||
Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n"
|
||||
break
|
||||
} else {
|
||||
Write-Error "Error in retrieving DRaaS Information"
|
||||
Write-Error "`n($_.Exception.Message)`n"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if($requests.StatusCode -eq 200) {
|
||||
$json = ($requests.Content | ConvertFrom-Json)
|
||||
|
||||
$draasId = $json.id;
|
||||
$draasState = $json.site_recovery_state;
|
||||
$srmNode = $json.srm_node.ip_address;
|
||||
$srmNodeState = $json.site_recovery_state;
|
||||
$vrNode = $json.vr_node.ip_address;
|
||||
$vrNodeState = $json.vr_node.state;
|
||||
$draasUrl = $json.draas_h5_url;
|
||||
|
||||
if($srmNodeState -eq "ACTIVATED") {
|
||||
if($Troubleshoot) {
|
||||
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasVersionUrl`n"
|
||||
}
|
||||
|
||||
try {
|
||||
if($PSVersionTable.PSEdition -eq "Core") {
|
||||
$requests = Invoke-WebRequest -Uri $draasVersionUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck
|
||||
} else {
|
||||
$requests = Invoke-WebRequest -Uri $draasVersionUrl -Method $method -Headers $global:draasConnection.headers
|
||||
}
|
||||
} catch {
|
||||
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
|
||||
Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n"
|
||||
break
|
||||
} else {
|
||||
Write-Error "Error in retrieving DRaaS Information"
|
||||
Write-Error "`n($_.Exception.Message)`n"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if($requests.StatusCode -eq 200) {
|
||||
$json = ($requests.Content | ConvertFrom-Json).node_versions
|
||||
|
||||
$srmVersion,$srmDescription = ($json | where {$_.node_ip -eq $srmNode}).full_version.split("`n")
|
||||
$vrVersion,$vrDescription = ($json | where {$_.node_ip -eq $vrNode}).full_version.split("`n")
|
||||
|
||||
$results = [pscustomobject] @{
|
||||
ID = $draasId;
|
||||
DRaaSState = $draasState;
|
||||
SRMNode = $srmNode;
|
||||
SRMVersion = $srmVersion;
|
||||
SRMNodeState = $srmNodeState;
|
||||
VRNode = $vrNode;
|
||||
VRVersion = $vrVersion;
|
||||
VRNodeState = $vrNodeState;
|
||||
DRaaSURL = $draasUrl;
|
||||
}
|
||||
|
||||
$results
|
||||
}
|
||||
} elseif ($srmNodeState -eq "ACTIVATING" -or $srmNodeState -eq "DEACTIVATING") {
|
||||
$results = [pscustomobject] @{
|
||||
ID = $draasId;
|
||||
DRaaSState = $draasState;
|
||||
SRMNode = $srmNode;
|
||||
SRMNodeState = $srmNodeState;
|
||||
VRNode = $vrNode;
|
||||
VRNodeState = $vrNodeState;
|
||||
DRaaSURL = $draasUrl;
|
||||
}
|
||||
|
||||
$results
|
||||
} else {
|
||||
Write-Host "`nDRaaS is currently deactivated, please run Set-DRaas -Activate`n"
|
||||
}
|
||||
} else {
|
||||
Write-Host "`nDRaaS has not been activated before, please run Set-DRaas -Activate`n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Function Set-DRaas {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: 05/23/2019
|
||||
Organization: VMware
|
||||
Blog: http://www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Activate or deactivate DRaaS for a given SDDC
|
||||
.DESCRIPTION
|
||||
This cmdlet activates or deactivates DRaaS for a given SDDC
|
||||
.EXAMPLE
|
||||
Get-DRaas
|
||||
#>
|
||||
Param (
|
||||
[Switch]$Activate,
|
||||
[Switch]$Deactivate,
|
||||
[Switch]$Troubleshoot
|
||||
)
|
||||
|
||||
If (-Not $global:draasConnection) { Write-error "No DRaaS Connection found, please use Connect-DRaaS" } Else {
|
||||
$draasUrl = $global:draasConnection.server
|
||||
|
||||
if($Activate) {
|
||||
$method = "POST"
|
||||
|
||||
if($Troubleshoot) {
|
||||
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasUrl`n"
|
||||
}
|
||||
|
||||
try {
|
||||
if($PSVersionTable.PSEdition -eq "Core") {
|
||||
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck
|
||||
} else {
|
||||
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers
|
||||
}
|
||||
} catch {
|
||||
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
|
||||
Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n"
|
||||
break
|
||||
} else {
|
||||
Write-Error "Error in activating DRaaS"
|
||||
Write-Error "`n($_.Exception.Message)`n"
|
||||
break
|
||||
}
|
||||
}
|
||||
Write-Host "`nActivating DRaaS, this will take some time and you can monitor the progress using Get-DRaaS or using the VMC Console UI`n"
|
||||
} elseif ($Deactivate) {
|
||||
$method = "DELETE"
|
||||
|
||||
if($Troubleshoot) {
|
||||
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasUrl`n"
|
||||
}
|
||||
|
||||
try {
|
||||
if($PSVersionTable.PSEdition -eq "Core") {
|
||||
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck
|
||||
} else {
|
||||
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers
|
||||
}
|
||||
} catch {
|
||||
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
|
||||
Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n"
|
||||
break
|
||||
} else {
|
||||
Write-Error "Error in deactivating DRaaS"
|
||||
Write-Error "`n($_.Exception.Message)`n"
|
||||
break
|
||||
}
|
||||
}
|
||||
Write-Host "`nDeactivating DRaaS, this will take some time and you can monitor the progress using Get-DRaaS or the VMC Console UI`n"
|
||||
} else {
|
||||
Write-Error "Invalid Operation"
|
||||
}
|
||||
}
|
||||
}
|
||||
98
Modules/VMware.HCX/VMware.HCX.psd1
Normal file
98
Modules/VMware.HCX/VMware.HCX.psd1
Normal file
@@ -0,0 +1,98 @@
|
||||
<#
|
||||
Copyright 2021 VMware, Inc.
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
#>
|
||||
|
||||
#
|
||||
# Module manifest for module 'VMware.HCX'
|
||||
#
|
||||
# Generated by: wlam@vmware.com
|
||||
#
|
||||
# Generated on: 09/11/18
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'VMware.HCX.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.0.2'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '88898ed6-26e8-4dfa-a9de-10d3a12571de'
|
||||
|
||||
# Author of this module
|
||||
Author = 'William Lam'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'VMware'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = '(c) 2018 VMware. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = 'PowerShell Module for Managing Hybrid Cloud Extension (HCX) on VMware Cloud on AWS'
|
||||
|
||||
# Minimum version of the Windows PowerShell engine required by this module
|
||||
PowerShellVersion = '6.0'
|
||||
|
||||
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
|
||||
|
||||
FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Get-HcxEndpoint', 'New-HcxMigration', 'Get-HcxMigration', 'Connect-HcxVAMI',
|
||||
'Get-HcxVCConfig', 'Set-HcxLicense', 'Set-HcxVCConfig', 'Get-HcxNSXConfig', 'Set-HcxNSXConfig', 'Get-HcxCity', 'Get-HcxLocation', 'Set-HcxLocation',
|
||||
'Get-HcxRoleMapping', 'Set-HcxRoleMapping', 'Get-HcxProxy', 'Set-HcxProxy', 'Remove-HcxProxy', 'Connect-HcxCloudServer', 'Get-HCXCloudActivationKey',
|
||||
'Get-HCXCloudSubscription', 'New-HCXCloudActivationKey', 'Get-HCXCloud', 'Set-HCXCloud'
|
||||
|
||||
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
|
||||
CmdletsToExport = @()
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = '*'
|
||||
|
||||
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
|
||||
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 = ''
|
||||
|
||||
# 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 = ''
|
||||
|
||||
}
|
||||
1706
Modules/VMware.HCX/VMware.HCX.psm1
Normal file
1706
Modules/VMware.HCX/VMware.HCX.psm1
Normal file
File diff suppressed because it is too large
Load Diff
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"
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"Type": "AUTOMATED",
|
||||
"Data": {
|
||||
"Name": "LCFarmJson",
|
||||
"DisplayName": "FarmJsonTest",
|
||||
"AccessGroup": "Root",
|
||||
"Description": "created LC Farm from PS via JSON with NVIDIA GRID VGPU",
|
||||
"Enabled": null,
|
||||
"Deleting": false,
|
||||
"Settings": {
|
||||
"DisconnectedSessionTimeoutPolicy": "NEVER",
|
||||
"DisconnectedSessionTimeoutMinutes": 1,
|
||||
"EmptySessionTimeoutPolicy": "AFTER",
|
||||
"EmptySessionTimeoutMinutes": 1,
|
||||
"LogoffAfterTimeout": false
|
||||
},
|
||||
"Desktop": null,
|
||||
"DisplayProtocolSettings": {
|
||||
"DefaultDisplayProtocol": "PCOIP",
|
||||
"AllowDisplayProtocolOverride": false,
|
||||
"EnableHTMLAccess": false,
|
||||
"EnableCollaboration": false,
|
||||
"EnableGRIDvGPUs": true,
|
||||
"VGPUGridProfile": "grid_m10-8a"
|
||||
},
|
||||
"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
|
||||
}
|
||||
29
Modules/VMware.Hv.Helper/README.md
Normal file
29
Modules/VMware.Hv.Helper/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# 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 ViewAPI service
|
||||
|
||||
```
|
||||
Import-Module VMware.VimAutomation.HorizonView
|
||||
|
||||
# Connection to view API service
|
||||
$hvServer = Connect-HVServer -server <connection server IP/FQDN>
|
||||
$hvServices = $hvserver.ExtensionData
|
||||
|
||||
# List Connection Servers
|
||||
$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.3.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 = ''
|
||||
|
||||
}
|
||||
13372
Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1
Normal file
13372
Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1
Normal file
File diff suppressed because it is too large
Load Diff
188
Modules/VMware.Hv.Helper/docs/Add-HVDesktop.md
Executable file
188
Modules/VMware.Hv.Helper/docs/Add-HVDesktop.md
Executable file
@@ -0,0 +1,188 @@
|
||||
---
|
||||
external help file: VMware.HV.Helper-help.xml
|
||||
Module Name: VMware.HV.Helper
|
||||
online version:
|
||||
schema: 2.0.0
|
||||
---
|
||||
|
||||
# Add-HVDesktop
|
||||
|
||||
## SYNOPSIS
|
||||
Adds virtual machine to existing pool
|
||||
|
||||
## SYNTAX
|
||||
|
||||
```
|
||||
Add-HVDesktop [-PoolName] <String> [-Machines] <String[]> [[-Users] <String[]>] [[-Vcenter] <String>]
|
||||
[[-HvServer] <Object>] [-WhatIf] [-Confirm] [<CommonParameters>]
|
||||
```
|
||||
|
||||
## DESCRIPTION
|
||||
The Add-HVDesktop adds virtual machines to already exiting pools by using view API service object(hvServer) of Connect-HVServer cmdlet.
|
||||
VMs can be added to any of unmanaged manual, managed manual or Specified name.
|
||||
This advanced function do basic checks for pool and view API service connection existance, hvServer object is bound to specific connection server.
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
### EXAMPLE 1
|
||||
```
|
||||
Add-HVDesktop -PoolName 'ManualPool' -Machines 'manualPool1', 'manualPool2' -Confirm:$false
|
||||
```
|
||||
|
||||
Add managed manual VMs to existing manual pool
|
||||
|
||||
### EXAMPLE 2
|
||||
```
|
||||
Add-HVDesktop -PoolName 'SpecificNamed' -Machines 'vm-01', 'vm-02' -Users 'user1', 'user2'
|
||||
```
|
||||
|
||||
Add virtual machines to automated specific named dedicated pool
|
||||
|
||||
### EXAMPLE 3
|
||||
```
|
||||
Add-HVDesktop -PoolName 'SpecificNamed' -Machines 'vm-03', 'vm-04'
|
||||
```
|
||||
|
||||
Add machines to automated specific named Floating pool
|
||||
|
||||
### EXAMPLE 4
|
||||
```
|
||||
Add-HVDesktop -PoolName 'Unmanaged' -Machines 'desktop-1.eng.vmware.com'
|
||||
```
|
||||
|
||||
Add machines to unmanged manual pool
|
||||
|
||||
## PARAMETERS
|
||||
|
||||
### -PoolName
|
||||
Pool name to which new VMs are to be added.
|
||||
|
||||
```yaml
|
||||
Type: String
|
||||
Parameter Sets: (All)
|
||||
Aliases:
|
||||
|
||||
Required: True
|
||||
Position: 1
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -Machines
|
||||
List of virtual machine names which need to be added to the given pool.
|
||||
|
||||
```yaml
|
||||
Type: String[]
|
||||
Parameter Sets: (All)
|
||||
Aliases:
|
||||
|
||||
Required: True
|
||||
Position: 2
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -Users
|
||||
List of virtual machine users for given machines.
|
||||
|
||||
```yaml
|
||||
Type: String[]
|
||||
Parameter Sets: (All)
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Position: 3
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -Vcenter
|
||||
Virtual Center server-address (IP or FQDN) of the given pool.
|
||||
This should be same as provided to the Connection Server while adding the vCenter server.
|
||||
|
||||
```yaml
|
||||
Type: String
|
||||
Parameter Sets: (All)
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Position: 4
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -HvServer
|
||||
View API service object of Connect-HVServer cmdlet.
|
||||
|
||||
```yaml
|
||||
Type: Object
|
||||
Parameter Sets: (All)
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Position: 5
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -WhatIf
|
||||
Shows what would happen if the cmdlet runs.
|
||||
The cmdlet is not run.
|
||||
|
||||
```yaml
|
||||
Type: SwitchParameter
|
||||
Parameter Sets: (All)
|
||||
Aliases: wi
|
||||
|
||||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -Confirm
|
||||
Prompts you for confirmation before running the cmdlet.
|
||||
|
||||
```yaml
|
||||
Type: SwitchParameter
|
||||
Parameter Sets: (All)
|
||||
Aliases: cf
|
||||
|
||||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
## OUTPUTS
|
||||
|
||||
## NOTES
|
||||
|
||||
| | |
|
||||
|-|-|
|
||||
| Author | Praveen Mathamsetty |
|
||||
| Author email | pmathamsetty@vmware.com |
|
||||
| Version | 1.1 |
|
||||
| Dependencies | Make sure pool already exists before adding VMs to it. |
|
||||
|
||||
|
||||
### Tested Against Environment
|
||||
| | |
|
||||
|-|-|
|
||||
| Horizon View Server Version | 7.0.2, 7.1.0 |
|
||||
| PowerCLI Version | PowerCLI 6.5, PowerCLI 6.5.1 |
|
||||
| PowerShell Version | 5.0 |
|
||||
|
||||
## RELATED LINKS
|
||||
138
Modules/VMware.Hv.Helper/docs/Add-HVRDSServer.md
Executable file
138
Modules/VMware.Hv.Helper/docs/Add-HVRDSServer.md
Executable file
@@ -0,0 +1,138 @@
|
||||
---
|
||||
external help file: VMware.HV.Helper-help.xml
|
||||
Module Name: VMware.HV.Helper
|
||||
online version:
|
||||
schema: 2.0.0
|
||||
---
|
||||
|
||||
# Add-HVRDSServer
|
||||
|
||||
## SYNOPSIS
|
||||
Add RDS Servers to an existing farm.
|
||||
|
||||
## SYNTAX
|
||||
|
||||
```
|
||||
Add-HVRDSServer [-FarmName] <Object> [-RdsServers] <String[]> [[-HvServer] <Object>] [-WhatIf] [-Confirm]
|
||||
[<CommonParameters>]
|
||||
```
|
||||
|
||||
## DESCRIPTION
|
||||
The Add-HVRDSServer adds RDS Servers to already exiting farms by using view API service object(hvServer) of Connect-HVServer cmdlet.
|
||||
We can add RDSServers to manual farm type only.
|
||||
This advanced function do basic checks for farm and view API service connection existance.
|
||||
This hvServer is bound to specific connection server.
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
### EXAMPLE 1
|
||||
```
|
||||
Add-HVRDSServer -Farm "manualFarmTest" -RdsServers "vm-for-rds","vm-for-rds-2" -Confirm:$false
|
||||
```
|
||||
|
||||
Add RDSServers to manual farm
|
||||
|
||||
## PARAMETERS
|
||||
|
||||
### -FarmName
|
||||
farm name to which new RDSServers are to be added.
|
||||
|
||||
```yaml
|
||||
Type: Object
|
||||
Parameter Sets: (All)
|
||||
Aliases:
|
||||
|
||||
Required: True
|
||||
Position: 1
|
||||
Default value: None
|
||||
Accept pipeline input: True (ByValue)
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -RdsServers
|
||||
RDS servers names which need to be added to the given farm.
|
||||
Provide a comma separated list for multiple names.
|
||||
|
||||
```yaml
|
||||
Type: String[]
|
||||
Parameter Sets: (All)
|
||||
Aliases:
|
||||
|
||||
Required: True
|
||||
Position: 2
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -HvServer
|
||||
View API service object of Connect-HVServer cmdlet.
|
||||
|
||||
```yaml
|
||||
Type: Object
|
||||
Parameter Sets: (All)
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Position: 3
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -WhatIf
|
||||
Shows what would happen if the cmdlet runs.
|
||||
The cmdlet is not run.
|
||||
|
||||
```yaml
|
||||
Type: SwitchParameter
|
||||
Parameter Sets: (All)
|
||||
Aliases: wi
|
||||
|
||||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -Confirm
|
||||
Prompts you for confirmation before running the cmdlet.
|
||||
|
||||
```yaml
|
||||
Type: SwitchParameter
|
||||
Parameter Sets: (All)
|
||||
Aliases: cf
|
||||
|
||||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
## OUTPUTS
|
||||
|
||||
### None
|
||||
|
||||
## NOTES
|
||||
| | |
|
||||
|-|-|
|
||||
| Author | praveen mathamsetty. |
|
||||
| Author email | pmathamsetty@vmware.com |
|
||||
| Version | 1.1 |
|
||||
| Dependencies | Make sure farm already exists before adding RDSServers to it. |
|
||||
|
||||
### Tested Against Environment
|
||||
| | |
|
||||
|-|-|
|
||||
| Horizon View Server Version | 7.0.2, 7.1.0 |
|
||||
| PowerCLI Version | PowerCLI 6.5, PowerCLI 6.5.1 |
|
||||
| PowerShell Version | 5.0 |
|
||||
|
||||
## RELATED LINKS
|
||||
100
Modules/VMware.Hv.Helper/docs/Clear-HVEventDatabase.md
Executable file
100
Modules/VMware.Hv.Helper/docs/Clear-HVEventDatabase.md
Executable file
@@ -0,0 +1,100 @@
|
||||
---
|
||||
external help file: VMware.HV.Helper-help.xml
|
||||
Module Name: VMware.HV.Helper
|
||||
online version:
|
||||
schema: 2.0.0
|
||||
---
|
||||
|
||||
# Clear-HVEventDatabase
|
||||
|
||||
## SYNOPSIS
|
||||
Clears configurationof the configured Event Database
|
||||
|
||||
## SYNTAX
|
||||
|
||||
```
|
||||
Clear-HVEventDatabase [[-HvServer] <Object>] [-WhatIf] [-Confirm] [<CommonParameters>]
|
||||
```
|
||||
|
||||
## DESCRIPTION
|
||||
Clears configurationof the configured Event Database
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
### EXAMPLE 1
|
||||
```
|
||||
Clear-HVEventDatabase
|
||||
```
|
||||
|
||||
## PARAMETERS
|
||||
|
||||
### -HvServer
|
||||
Reference to Horizon View Server to query the virtual machines from.
|
||||
If the value is not passed or null then
|
||||
first element from global:DefaultHVServers would be considered in-place of hvServer
|
||||
|
||||
```yaml
|
||||
Type: Object
|
||||
Parameter Sets: (All)
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Position: 1
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -WhatIf
|
||||
Shows what would happen if the cmdlet runs.
|
||||
The cmdlet is not run.
|
||||
|
||||
```yaml
|
||||
Type: SwitchParameter
|
||||
Parameter Sets: (All)
|
||||
Aliases: wi
|
||||
|
||||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -Confirm
|
||||
Prompts you for confirmation before running the cmdlet.
|
||||
|
||||
```yaml
|
||||
Type: SwitchParameter
|
||||
Parameter Sets: (All)
|
||||
Aliases: cf
|
||||
|
||||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
## OUTPUTS
|
||||
|
||||
## NOTES
|
||||
| | |
|
||||
|-|-|
|
||||
| Author | Wouter Kursten |
|
||||
| Author email | wouter@retouw.nl |
|
||||
| Version | 1.0 |
|
||||
|
||||
===Tested Against Environment====
|
||||
| | |
|
||||
|-|-|
|
||||
| Horizon View Server Version | 7.4 |
|
||||
| PowerCLI Version | PowerCLI 10 |
|
||||
| PowerShell Version | 5.0 |
|
||||
|
||||
## RELATED LINKS
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user