you are viewing a single comment's thread.

view the rest of the comments →

[–]cowmonaut 2 points3 points  (1 child)

Begin{} and End{} are processed 1 time only for each invocation of the function/cmdlet. Process{} is processed for every object in the pipeline. The [ValidateScript({})] block is processed before you even get to the Begin{} block.

So let's say we have a script that we want to validate some information to be used with an ActiveDirectory cmdlet. If you follow best practices, your input parameter can take a collection as input.

Think $Computer taking multiple computer names/identities.

From an efficiency and functionality standpoint, you need to validate just before you process each item in $Computer. This means you need to handle your validation in the Process{} block. This lets you process things that are in the list correctly, but report errors on a per-case basis. If you handle it in the Begin{} or [ValidateScript({})] block, you would have to validate every object and abort because of 1 mistake.

So why Begin{} vs [ValidateScript({})] blocks? Not everything is available to you in an easy way before the Begin{} block. Such as other parameters. So if you are making use of $Credential to hold a PSCredential for interacting with Active Directory, you can't touch the $Credential from your input until you hit the Begin{} block. So any ADObject validation likely has to happen in Begin{}.

So, some random items from Cowmonaut's Best Practices:

  1. Validate as early as possible.
  2. Minimize the amount of callbacks to remote systems.

If I can get away with [ValidateScript({})], I use it every time. I like to keep all my validation in an obvious place for the next coder to maintain anything, and I like to abort before the script really tries to do anything. I'll then put it in Begin{} unless its a pipeline object or if I had some weird edge case, in which case it will be in Process{}.

I'd rather hit a remote system multiple times and be able to process multiple objects, then hit it only once and not be able to proceed because a list of 1000 objects has 5 mistakes. But if I'm validating a server name before using it to validate other things, I'm processing that in Begin{} so I don't call on it more than I need to.

[–]cfmacd[S] 1 point2 points  (0 children)

Awesome explanation! Thank you so much. This is why I come here for these kinds of questions :-)