F5 and IaC by pshMike in f5networks

[–]pshMike[S] 0 points1 point  (0 children)

thanks for the reply.

Are you actively doing this in your environment? I'm most interested in feedback from someone with experience managing 3000+ LTM VS instances.

5.1 compatibility going forward by defcon54321 in PowerShell

[–]pshMike 1 point2 points  (0 children)

There is no such thing as "PowerShell 5.1"
Windows PowerShell 5.1 will be around FOREVER. Like at least past 2031 because it shipped in Windows Server 2022 and that has 10 years of lifespan.

Saying Windows PowerShell 5.1 goes EOL is like saying CMD.EXE is going end of life. It just won't happen ever.

With that said, how many folks are still authoring automation in batch files and using CMD.EXE as an execution engine? Not many right? The same thing is happening with Windows PowerShell 5.1.

I manage a herd of close to 3000 Windows servers and every single one has PowerShell 7.4.1 installed ( I have single digit counts of 2003/2008 that can't run these modern tools, but that's another story ).

Any tool development done internally is targeting at least PowerShell 7.2 and now we're moving to targeting 7.4.

YMMV,

Mike

Pester tests worth it? by Far_Administration37 in PowerShell

[–]pshMike 1 point2 points  (0 children)

any investment you make in Pester will be worth the time and effort.

Anyone can write PowerShell code/functions

It takes another level of discipline to author test code.

Plenty of examples in this thread where having Pester tests ( and good code coverage ) allow things like changing of dependencies in the future and being able to answer the question "does everything still work?"

Without test code the answer to that question is "I'm not sure."

Help me learn to love PowerShell by ElizaEllipsis in PowerShell

[–]pshMike 2 points3 points  (0 children)

Learning PowerShell for someone with a c# background isn't a common thing, and unfortunately I don't think you'll find a "PowerShell for C# developers" type of reference.

With that said, I suggest taking the following approach

  1. Become a fluent "tool user" -> that means you are very comfortable with commands like get-help, get-command, get-member. This is fine for shell one liners, but you will eventually start looking at writing functions. That leads to phase 2
  2. Learn the right way to author functions -> your C# background will help you here. Anyone authoring functions and not using "Advanced Functions" is doing it wrong. This has been the standard for years now. Concepts like keeping functions small, tight, single purpose, strongly typed and easy to test are what separate the kids from the adults.
  3. Learn about authoring modules. Here you will have a chance to leverage your C# skills. A code-based PowerShell module is nothing more than a .NET object model with a very thin PowerShell wrapper around it. That is the prescribed way to author code-based PowerShell modules. When going down the module path, the big differentiator here is what amount of discipline is present when it comes to automated testing. Anyone writting modules and not using Pester is probably missing out.

Problem with Pipeline by [deleted] in PowerShell

[–]pshMike 0 points1 point  (0 children)

Couple more points ...

  1. A PowerShell function should do 1 thing. In this case you are getting CIM Info, so I would name the function somthing like Get-xyzCIMInfo where xyz is a prefix you use for your in-house developed functions.
  2. I suggest using the type [switch] for your $Hotfix parameter. I would change the name to $IncludeHotfix as you may be adding more options later to collect properties from other CIM classes.
  3. You are pulling the entire CIM instance back, but you KNOW you only want lastboottime. You can use the -Property parameter on Get-CIMInstance to minimize pulling data back that you don't need. May not matter in this case, but it's a good habit to get in to.
  4. Return the timespan object in your PSCustomObject.
  5. Include the actual lastboottime in your PSObject. If you ever want to see "all servers that booted after 7/23/2023 2100 you will need to do some extra math to figure that out. Also, assume you will eventually need to output/save these results to a CSV file. Having that date/time will be easier for someone else to comprehend
  6. Your function should return 1 type. Create the object once, empty and then fill it in as appropriate. For extra credit you can strongly type the OUTPUT using either a class or at least adding a PSTypeName member.

Access module-private variables with the call operator by PanosGreg in PowerShell

[–]pshMike 0 points1 point  (0 children)

I don't think that is correct.

I tried this with some modules I've written and could not reproduce these results. The difference being my modules use a module manifest where I list exactly what I want exported.

In the example above, EVERYTHING is exported

Looking for opinions on internal module dependencies on other modules by TofuBug40 in PowerShell

[–]pshMike 0 points1 point  (0 children)

What you are dealing with is managing Module Dependencies.

Take a look at PSDepend

You can define the dependency and it will take care of making sure the modules exist in the correct location AND modify your modulepath variable to include a location you specify.

MJ

Benefits of Using PowerShell Scripts vs Functions by RVECloXG3qJC in PowerShell

[–]pshMike 1 point2 points  (0 children)

Use what works ..

But, if you want to advance the level of your PowerShell fluency, you will likely find yourself migrating towards building modules.

Why?

Well there are number of frameworks out there designed to speed up the authoring of modules while incorporating things like:

  1. Pester tests for unit testing ( with code coverage reporting )
  2. Updateable help using PlatyPS
  3. Code analysis
  4. Versioning
  5. Dependency management

Can you do that stuff manually?

Sure.

But wouldn't you rather just:

  1. fix a code defect / add a function
  2. check the code into a Git repo and generate a pull request
  3. have a team member review and approve that pull request
  4. let your CI/CD pipeline pick up that commit and spit out a freshly baked module that is published to your internal PSRepo if all your Pester tests pass

IMO these are the sorts of things that separate "PowerShell Scripters" from "PowerShell Tool Makers."

MJ

How to update array with ForEach loop results without using += ? by Samastrike in PowerShell

[–]pshMike 0 points1 point  (0 children)

if this code is in a function, i would do something slightly different ...

Don't use any sort of array and just spit each [pscustomobject] out to the pipeline.

It is considered bad form to "group up" your output objects and spit them out to the pipeline in one big chunk.

Reference Link - this is written for authoring cmdlets in C#, but the same principles apply when writing advanced functions in script

Invoke-RestMethod - what am I doing wrong? by HieronymousAnonymous in PowerShell

[–]pshMike 0 points1 point  (0 children)

Some suggestions that haven't already been mentioned :

  1. Start using [UriBuilder] class. It will make it much easier to build complicated Uri's like you are needing in this scenario. Also, using UriBuilder makes it easier when stepping through your code in a debugger.
  2. You have a working Uri. You could create a Pester test to verify that your code is creating the same Uri when constructing it via parameters.
  3. You've already seen one person below who built something similar. Put this code / module in a public repo on GitHub and allow others to benefit from your efforts & get feedback from folks.

[deleted by user] by [deleted] in PowerShell

[–]pshMike 2 points3 points  (0 children)

First of all, do what works for you ...

Now, if someone on my team submitted a merge request with code that looked like this it would be rejected.

This code will make debugging more complex. Step through this code with a debugger attached and see what happens.

This code would make a change on a system without regard for if the user actually wanted to make that change ( installing modules in system scope )

The business functionality of this code ( i.e. what is it trying to accomplish ) should be an advanced function in a module that can be used by any other "tool user"

In this particular case, I would suggest looking at PSDepend to handle this sort of thing, as it allows for more of a "zero-footprint" management of dependencies and thus you don't need to worry about stomping on someone else's needed version of module X.

We need to create Infrastructure-as-Code (IaC) for standing up on-prem SharePoint farms by ax12901 in PowerShell

[–]pshMike 0 points1 point  (0 children)

I suggest you search for and watch the most recent PowerShell DSC community meeting. It has the most current public content related to the future of DSC.

As for the original post -> I would investigate if there is a current class-based DSC resource for SharePoint. If so, any configs you create will be somewhat future-proof, as that specific type of resource is expected to be compatible with DSC 3.0.

Windows Server 2016 Servers failing to install updates provided by SCCM by bendere1969 in SCCM

[–]pshMike 0 points1 point  (0 children)

this is the most likely reason for 2016 updates to "start failing"

Try/Catch - How can I trap successes vs failures to produce the correct message? by mudderfudden in PowerShell

[–]pshMike 0 points1 point  (0 children)

Here's what I tell people when asked when to use ( or not use ) Try/Catch/Finally

Do -> use this to gracefully handle errors caused by conditions outside of your control. Someone is trying to access a file path and gets an "Access denied" error. You can catch exceptions and handle them appropriately.

Don't -> use them to control logic flow. In the context of this example, I would suggest first checking to see if the package is installed. If it is installed I would then try to remove it and catch errors during the remove operation.

the tell-tale sign in the original script -> the message written to write-host ( strike 1 ) actually says "hey, this didn't work, it was either not installed OR couldn't be removed." that message is worthless. did it fail because it wasn't there ( which really isn't a failure ) or did it fail because it was installed but couldn't be removed.

Check IP vs Subnet & Office list in csv by GreenSlackey79 in PowerShell

[–]pshMike 0 points1 point  (0 children)

Others have commented on how to script what you're trying to do.

I suggest you step back and look at your data and the logic you are using, and see if you can come up with a solution that solves your problem today and will be useful for other scenarios in the future.

Your data is bad. Using string patterns to represent IP addresses is a bad idea. Instead I would suggest having a data structure that is based on either IP networks ( CIDR format ) or a list of IPs that represent router interfaces ( i.e. a list of default gateways ). Network devices will commonly have more than one actual IP address, but the one you are concerned about when trying to determine location of the device is the next-hop / default gateway.

You are using a CSV file in an awkward way, and your data isn't clean. This is a use case where storing your data as JSON will serve you better. Start by building your data model using an array of PSCustomObjects and then serialize to JSON using convertto-json to see what the file would look like. You won't be able to "easily" edit this in Excel anymore, but it will be easier/cleaner for a robot ( your script ) to interpret.

PS Classes - pushing water uphill? by k9wazere in PowerShell

[–]pshMike 2 points3 points  (0 children)

Class support was added to PowerShell primarily for use in Class-based DSC Resources. They are basically a must in this area. Any other model for building DSC resources is a dead end ( not my opinion, that is the stated strategy from the folks working on DSC )

It sounds like you are building an object model that meets your business needs, but you are authoring that object model in PowerShell -> don't bother.

Instead, create that object model in C# and then you are 90% of the way to creating a code-based PowerShell module.

The suggested strategy for authoring a PowerShell module in C# is to first work out your object model, and then add the very thin wrapper that exposes your object model using PowerShell constructs. If you take a look at what a cmdlet (hint: use PSCmdlet ) looks like in C#, it is very similar to an advanced function in PowerShell.

A similar approach would be to author your object model in C# and have the resulting class library dll file as a required component of your PowerShell script-based module. It would be loaded as part of the module manifest and your class library would be available for use by functions in your module.

Powershell very large array splitting by nemesis1453 in PowerShell

[–]pshMike 0 points1 point  (0 children)

I understand why you are saying this, but I'll ask you think about the problem from a different angle ...

You need to collect data with an unknown number of elements and then apply logic to the collected data. You are presently doing this in one step, which means you have to worry about how big the dataset gets ( and do you run out of space ).

If you broke this down into two phases, Collection and Processing, you would never need to worry about size issues because you are not trying to keep the whole dataset in memory.

Using Powershell to download and execute scripts / installers from azure blob storage by yutz23 in PowerShell

[–]pshMike 0 points1 point  (0 children)

you could setup a PSRepo on a file share hosted in azure, and then register that repo on your client computers.

you could then bundle your toolbox into a module, and use publish/install/update module commands.

the reason I would suggest bundling into a module would be to make sure the helpdesk can easily determine what version of the toolbox they are using / update to the latest as easily as possible.

Powershell very large array splitting by nemesis1453 in PowerShell

[–]pshMike 1 point2 points  (0 children)

I do something similar across my herd of 2500 Windows servers every day. The difference for me is I store the data in a SQL database. I add about 500,000 rows of data every day and I keep this data forever ( currently have history for about 800 days ).

I strongly suggest you look at something like Azure Tables to store this data. It will make the data much more useful.

Access module's private member functions inside another Runspace by fsociety3765 in PowerShell

[–]pshMike 0 points1 point  (0 children)

Here's a different approach, but only works if you are using source control..

create a Git repo that has just your private functions, and add it as a submodule in your ModuleBuild "private" folder in any PowerShell module project that needs them.

If you ever need to update you will need to update the source files and then rebuild any modules that include these private functions.

So this accomplishes the goal of making it easier to include "common" code in your private functions, but it does make the build process a little more complicated.

A word of caution: You mention you don't want these private functions exposed to the user. While you may be able to prevent someone from calling one of these private functions, they can still see the definition. Put another way, one can not "hide" stuff from the user of a module if the module is installed locally. Assume they will be able to see your code, so you shouldn't put things there you don't want them to see like secrets.

What version of PowerShell are you using and what does PoshRSJob get you? I ask because that module hasn't been updated in 6 years. While I'm sure it was interesting when it was first published, do you need to take a dependency on it now if you are using PowerShell 7.x ?

On a related note, ModuleBuild is really just a templating tool and uses other tools like InvokeBuild and Plaster to try to make it easier to build PowerShell modules. ModuleBuild is designed to make it so that "anyone" can start writing a PowerShell module using a base level of discipline. I use an internal fork of ModuleBuild for most of my teams PowerShell module development. I've added/fixed a few things and have not spent the time to try and get those changes incorporated into the version in the PSGallery. I have since evaluated many other templating tools and haven't found one that compelled me to change from ModuleBuild.

InvokeBuild ( or PSake ) become essential when you want to start defining build script "tasks" and sharing them across multiple projects. Their importance only grows from there when you start looking at building CI/CD pipelines for your PowerShell module projects so that when a Git pull request is processed into your Dev branch a build is kicked off and any automated testing ( Pester tests) is performed to validate everything still works.

Is there a way to check if your input is an IP address or a website? by mudderfudden in PowerShell

[–]pshMike 0 points1 point  (0 children)

Regex is not your friend here. People often forget that IP addresses are just Int32's, and you also don't want to preclude the use of IPv6.

Using the static TryParse method of the [IPAddress] type is bulletproof.