VMware Cloud Community
JLogan2016
Enthusiast
Enthusiast
Jump to solution

Datastore and VMHost vs Cluster

I have a request right now to build a GUI around a working PowerCLI script that creates a new VM based on fields entered by a tech. The GUI looks like this:

pastedImage_1.png

As this will be done by "associate" techs who may not have the access or experience to troubleshoot issues very deeply, I am trying to both simplify the GUI and ensure the script has necessary error checking. One item that I am mulling over is the host/datastore. Rather than having 4 fields (Host, Cluster, Datastore, Datastore Cluster) I would just like to have two, and do the worrying on the back end. In the script I have been playing about with a couple of different ways to do this - an if statement didn't seem to work the way I wanted so I settled on a Try/Catch like so:

    try {

        Get-DatastoreCluster -Name C-CAD-1 -ErrorAction Stop

    }catch [Exception] {

        Get-Datastore -Name C-CAD-1

    }

    try {

        Get-Cluster -Name mas-vms01.dartcontainer.com -ErrorAction Stop

    }catch [Exception] {

        Get-VMHost mas-vms01.dartcontainer.com

    }

My question is, is this the best way to do it? Am I setting myself up for headaches down the road? Any thoughts/suggestions would be welcome.

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

That is a good and clean solution imho.
Can't think of a better one. You have my blessings :smileygrin:


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
5 Replies
LucD
Leadership
Leadership
Jump to solution

That is a good and clean solution imho.
Can't think of a better one. You have my blessings :smileygrin:


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
JLogan2016
Enthusiast
Enthusiast
Jump to solution

Thanks, much appreciated. On that note, if this seems to be the correct way, I have a follow-up question. In this scenario the tech fills out the fields in the GUI (created in another language), and clicks on the button. This fires a function that pulls all of the field values into an array. My intent was to then simply call the powershell script, passing the indices as parameters. The problem I am running into is defining the params in the ps script. As an example, here is a small reproducer:

Param (

   [string]$sVM,

   [string]$iCPU,

   [string]$iRAM,

   [string]$sIP,

   [string]$sSubnet,

   [string]$sGateway,

   [string]$sDNS,

   [string]$sDescription,

   [string]$sSite,

   [string]$sHost,

   [string]$sDStore,

   [string]$sTemplate,

   [string]$sSpec,

   [string]$sFolder,

   [string]$sOU

)

Write-Host $args.Count "args"

    ForEach ($sArg in $args) {

        Write-Host $sArg

    }

If I call the script as written, it appears to find none of the parameters:

./Args.ps1 SPERA-SCCM01 4 16 10.10.120.115 255.255.255.0 10.10.115.254 10.10.1.120 "SCCM 2016 Server" ERA ER-vms33.mycompany.com Dev-ERA-App01 "ER 2016 Template 02" ScriptERADomain ScriptDeploy "OU=Patch Reboot,OU=ERA,OU=Servers,DC=mycompany,DC=com"

0 args

If, however, I add something to the first line, even a simple cls, I get an error on Param (which I would expect, it not being the first line), but the resultant output is more inline with what I would expect:

Param : The term 'Param' is not recognized as the name of a cmdlet, function, script file, or operable program. Check
the spelling of the name, or if a path was included, verify that the path is correct and try again.
At desktop\Args.ps1:3 char:1
+ Param (
+ ~~~~~
+ CategoryInfo : ObjectNotFound: (Param:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

15 args
SPERA-SCCM01
4
16
10.10.120.115
255.255.255.0
10.10.115.254
10.10.1.120
SCCM 2016 Server
ERA
ER-vms33.mycompany.com
Dev-ERA-App01
ER 2016 Template 02
ScriptERADomain
ScriptDeploy
OU=Patch Reboot,OU=ERA,OU=Servers,DC=mycompany,DC=com

I feel like I am missing something insanely simple, but cannot seem to see what it is. I don't get why the inclusion of a line above the Param call (regardless of what that line is) gives me what I want.

0 Kudos
JLogan2016
Enthusiast
Enthusiast
Jump to solution

I think I figured it out. It appears the automatic variable $args only takes the overflow from the command line. If I call the variables ($sVM, etc.) explicitly I get the return I would expect.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Afaik there are 2 ways of doing that.

  1. Without a Param statement. All arguments will be stored $args

        Your script can look like this

Write-Host "Arg1: $($args[0])"

Write-Host "Arg2: $($args[1])"

Write-Host "Arg3: $($args[2])"

      

     Then you can call like this

PS C:\> D:\Scripts\test.ps1 A B 1

Arg1: A

Arg2: B

Arg3: 1

     2. With a Param statement.

param(

    [string]$arg1,

    [string]$Arg2,

    [int]$Arg3

)

Write-Host "Arg1: $($Arg1)"

Write-Host "Arg2: $($Arg2)"

Write-Host "Arg3: $($Arg3)"

     Then you can call like this

PS C:\> D:\Scripts\test.ps1 -Arg1 A -Arg2 B -Arg3 1

Arg1: A

Arg2: B

Arg3: 1

or like this

PS C:\> D:\Scripts\test.ps1 A B 1

Arg1: A

Arg2: B

Arg3: 1

Powershell will do the casting to the correct type, which it knows through the Param declarations


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
JLogan2016
Enthusiast
Enthusiast
Jump to solution

Thanks for the additional insight. At this point I am unsure yet how I am going to proceed. I don't have the patience for GUIs in PowerShell, so I created it in another language. When the user is done adding VMs, they end up with a dynamic array that looks something like this:

pastedImage_0.png

My original plan had been to simply iterate through the array indices and call the PowerCLI script to create the VM with the parameters defined. But it dawned on me that the script makes the connection to the vCenter server first, which means if I call it repeatedly I am going to be calling Connect-VIServer potentially dozens of times. I could export the array to a csv and then import into the script, but as that is precisely what they are trying to get away from it seems counter-productive. The only other option I can see at the moment is to run two scripts, one to make the connection to vCenter and then another to run the create VM function, but am guessing I will run into scope issues.

Regardless, thanks as always for the help and information. I am sure I will have more questions to post Smiley Happy

0 Kudos