Tag Archives: count

UX Headache – Joining Lines in a Text File

A part of me seriously wants to be involved in UX. I constantly find problems with just about every UI in which I interface. This one is beautiful, but it is lacking. This one is ugly, but works. Maybe it’s why I love PowerShell; it’s always the same no matter what I’m working with. It’s probably also why I wish every website on the planet was written with APIs first. What an amazing world, if I could do everything using PowerShell: check the bank, register children for school, order Chipotle, and make appointments at the doctor, the dentist, the eye doctor, the auto shop, etc. The list is endless.

Anyway, back to the topic here. I’ve often considered buying a new domain and pointing out awful, real-world experiences of my own until someone comes along, realizes I get it, and employs me to stop all the awful interfaces… at least for that company. Us humans, living in this digital world, are constantly subjected to awful-looking, unhelpful, and inconsistent interfaces that have become a requirement in our lives. If I request that your site show me 100 rows at a time, then it’s not likely I’m going to change my mind when I click into one record and then go back out to the row view again. And if I do want to change it, guess what, that’s on me. I could go on for days.

The company responsible for those, two paragraphs is the reason I’m writing today. I was sent a list of 100 or 200 CIDR ranges. No problem, I’ll just copy and paste them into that one box on the website set to accept both single IPs and CIDR ranges. Nope. That caused an error. It was unable to parse it, and so now it was my job to enter them one at a time!? Well, it would’ve been had I not known PowerShell. Seriously, someone somewhere might be doing that. Copy and paste, or select and drag, or whatever other option was left. Whichever method, it would be much slower than what I did. So, today’s post is both me venting a little of my pent-up UX frustration and providing a quick resolution for anyone in this same situation, that didn’t automatically think PowerShell themselves. You see, the interface would take a comma-separated list, it just couldn’t handle a line-delimited list–if that’s even what that’s called. Maybe new-line-delimited; I don’t know for sure.

Here’s what I had (after removing the public IP addresses):

10.138.80.0/22
10.138.87.160/27
10.138.91.160/27
10.138.129.0/29
10.139.33.96/28
10.139.38.0/27
10.224.1.32/27
10.224.41.128/25
10.224.43.0/24
10.224.73.0/25
10.228.21.192/27
10.120.1.0/27
10.128.1.32/27
10.128.11.64/26
10.128.29.0/24
10.128.205.128/26
10.130.66.0/25
10.152.7.160/27
10.152.12.0/24
10.152.13.0/24
10.152.14.0/24
10.152.15.0/27
10.156.20.0/28
10.156.20.16/28
10.156.20.32/27
10.156.20.96/27
10.156.24.0/22
10.156.28.128/26
10.156.29.0/24
10.156.30.0/24
10.156.31.0/24
10.156.32.0/24
10.156.33.0/24
10.156.34.0/24
10.156.35.0/24
10.156.36.0/24
10.156.42.0/24
10.156.43.0/24
10.160.20.0/25
10.161.43.0/25
10.161.43.128/25
10.161.44.0/22
10.161.48.0/22
10.162.2.0/27
10.166.9.0/24
10.192.237.0/26
10.192.238.0/24
10.192.255.0/25
10.193.120.0/25
10.193.120.128/25
10.193.121.0/25
10.193.121.128/25
10.193.122.0/25
10.193.122.128/25
10.193.123.0/25
10.193.123.128/25
10.193.124.0/25
10.193.124.128/25
10.193.125.0/25
10.208.17.0/24
10.208.21.0/24
10.224.21.0/25
10.224.40.0/24
10.224.61.192/26
10.224.71.32/27
10.224.71.160/27
10.224.72.192/27
10.224.74.0/23
10.224.78.0/24
10.224.81.0/25
10.224.81.128/25
10.224.82.64/26
10.224.83.0/24
10.224.100.0/22
10.224.104.0/22
10.224.108.0/22
10.224.112.0/22
10.224.116.0/22
10.224.120.0/22
10.224.124.0/22
10.224.128.0/23
10.224.130.0/23
10.224.132.0/23
10.224.134.0/23
10.224.136.0/23
10.224.138.0/23
10.224.140.0/23
10.224.142.0/23
10.224.148.0/22
10.226.3.0/26
10.229.16.0/23
10.230.12.128/25
10.140.76.0/24
10.140.78.0/28
10.140.102.0/24
10.140.103.0/24
10.140.113.0/24
10.140.138.0/24
10.140.139.0/26
10.120.1.32/28
10.128.167.32/27
10.192.178.64/26
10.194.3.128/25
10.224.5.128/26
10.224.42.0/25
10.224.76.0/24
10.224.77.0/24
10.224.79.0/24
10.224.96.0/22
10.140.100.0/24
10.140.101.0/24
10.140.104.0/24
10.140.105.0/24
10.140.106.0/24
10.193.120.0/21
10.130.169.0/24
10.224.9.0/24

Let’s save this file to my computer as C:\Users\tommymaynard\Documents\CIDR.txt. Now, let’s see how many entries we’re working with. What kind of time might I save?

$Path = 'C:\Users\tommymaynard\Documents\CIDR.txt'
(Get-Content -Path $Path).Count
117

We’re working with 117 entries, or rather, 116 commas. Yeah, I’m not moving those over one by one; I don’t have the kind of time during my day. Enter PowerShell. To begin testing, I chose a smaller subset of the CIDR ranges. When I was happy with that, which was practically immediately, I added the -join operator.

Get-Content -Path $Path | Select-Object -First 5
10.138.80.0/22
10.138.87.160/27
10.138.91.160/27
10.138.129.0/29
10.139.33.96/28
(Get-Content -Path $Path | Select-Object -First 5) -join ','
10.138.80.0/22,10.138.87.160/27,10.138.91.160/27,10.138.129.0/29,10.139.33.96/28

Once I had this, I only had two things left to do. One, test to see if the company’s UI accepted comma-separated entries like this, and two, if it did, then join all 117 addresses with a comma in between each, and carry on with my day. That’s three things. Well, four if you count writing up this post after work. The UI did accept things that way, and so I ran the below command, pasted it in the box, saved everything, and reported back to my customer that it was set and done, as requested. Next.

(Get-Content -Path $Path) -join ',' | Set-Clipboard

AWS PowerShell Command Count

Back in the day, I was astonished by the number of PowerShell commands that AWS (Amazon Web Services) had written. It was a huge number—I believe it was around 5,000. There’s probably a post or two on this site where it’s mentioned. Based on the number, it was clear that AWS had made a commitment to (wrapping their APIs with) PowerShell. Back then, it was easy to calculate the number of commands because of that single, PowerShell module. Install the module, count the commands (programmatically of course), and done. Over the last two or three years—I’m not 100% sure—-they moved to a model where modules are separated out by service. I greatly suspect that the single-module model was no longer suitable. Who wants to import a few thousand commands by default, when they only needed maybe one or two? Over time, I suspect that it probably wasn’t the most efficient way in which to handle the high number of commands.

Now, AWS has modules with names that begin with AWS.Tools. In the below example, I have assigned the $AWSModules variable with all the AWS modules located in the PowerShell Gallery that begin with the name AWS.Tools.*.

$AWSModules = Find-Module -Name AWS.Tools.*
$AWSModules.Count
241
$AWSModules | Select-Object -First 10 -Property Name,Version
Name                              Version
----                              -------
AWS.Tools.Common                  4.1.10.0
AWS.Tools.EC2                     4.1.10.0
AWS.Tools.S3                      4.1.10.0
AWS.Tools.Installer               1.0.2.0
AWS.Tools.SimpleSystemsManagement 4.1.10.0
AWS.Tools.SecretsManager          4.1.10.0
AWS.Tools.SecurityToken           4.1.10.0
AWS.Tools.IdentityManagement      4.1.10.0
AWS.Tools.Organizations           4.1.10.0
AWS.Tools.CloudFormation          4.1.10.0

Once I determined that there were over 240 individual modules, I piped the $AWSModule variable to the Get-Member command to view its methods and properties. I didn’t know what I was after, but out of the returned properties, I was intrigued by the Includes property. I used that property as a part of the below command. Each of the 241 entries includes a Command, DscResource, Cmdlet, Workflow, RoleCapability, and Function nested property inside the Includes property.

$AWSModules.Includes | Select-Object -First 3
Name Value
---- -----
Command {Clear-AWSHistory, Set-AWSHistoryConfiguration, Initialize-AWSDefaultConfiguration, Clear-AWSDefaultConfiguration…}
DscResource {}
Cmdlet {Clear-AWSHistory, Set-AWSHistoryConfiguration, Initialize-AWSDefaultConfiguration, Clear-AWSDefaultConfiguration…}
Workflow {}
RoleCapability {}
Function {}
Command {Add-EC2CapacityReservation, Add-EC2ClassicLinkVpc, Add-EC2InternetGateway, Add-EC2NetworkInterface…}
DscResource {}
Cmdlet {Add-EC2CapacityReservation, Add-EC2ClassicLinkVpc, Add-EC2InternetGateway, Add-EC2NetworkInterface…}
Workflow {}
RoleCapability {}
Function {}
Command {Add-S3PublicAccessBlock, Copy-S3Object, Get-S3ACL, Get-S3Bucket…}
DscResource {}
Cmdlet {Add-S3PublicAccessBlock, Copy-S3Object, Get-S3ACL, Get-S3Bucket…}
Workflow {}
RoleCapability {}
Function {}

After some more inspection, I decided that each command populated the Command property and the Cmdlet or the Function property, as well, depending on what type of commands were included in the module. Next, I just returned the commands using dot notation. This isn’t all of them, but you get the idea.

$AWSModules.Includes.Command
Clear-AWSHistory
Set-AWSHistoryConfiguration
Initialize-AWSDefaultConfiguration
Clear-AWSDefaultConfiguration
Get-AWSPowerShellVersion
...
Remove-FISExperimentTemplate
Remove-FISResourceTag
Start-FISExperiment
Stop-FISExperiment
Update-FISExperimentTemplate

If you’re curious, as I was, Update-FISExperimentTemplate, “Calls the AWS Fault Injection Simulator UpdateExperimentTemplate API operation.” I have no idea.

With a little more dot notation, I was able to get the count.

$AWSModules.Includes.Command.Count
8942

And now, I know what I used to know. I also know that AWS has been busy. And, that they’ve continued to make a huge effort in the PowerShell space. If you don’t go straight to the PowerShell Gallery, and I would recommend you do, you can always start at the AWS PowerShell webpage.

Get the Total Parameter Count

Update: There was an update to this post on May 29, 2018. See below.

It’s been a littler longer than normal for me to have not written. My entire week last week didn’t include a post; it’s so weird. Well, I’m taking a quick minute — seriously — to discuss something I wanted to do recently.

In a new project I’m on, I wanted to know how many parameters a function has from inside the function itself. I didn’t want to know how many parameter were used when the function was invoked. Had I, I would’ve used $PSBoundParameters. Again, I wanted to know how many parameter(s) the function had, whether they were used or not.

I’ll tell you what I opted to do. On that note, do however, let me know if you come up with a better idea. I didn’t give this a ton of time. That said, it doesn’t even have to be better; I’d still like to hear about it. For me, I opted to execute a Get-Help command against the function, from inside the function. I’m making this a quick post, so let’s jump to some code.

Function Check-ParameterCount {
    [CmdletBinding()]
    Param (
        [Parameter()]
        [string]$Param01,

        [Parameter()]
        [string]$Param02,

        [Parameter()]
        [ValidateSet('Source','Destination')]
        [string]$Param03
    )

    $ParameterCount = (Get-Help -Name Check-ParameterCount).Parameters.Parameter.Count
    "There are $ParameterCount possible parameter(s) in this function not including the common parameters."
}
PS > Check-ParameterCount
There are 3 possible parameter(s) in this function.

The next example is the same example as above, however, we’ve removed the third parameter. Sure enough, the value is now two. As you may have noticed, Get-Help gets its parameter count from the actual parameter(s) themselves. Neither function has any comment-based help. Therefore, we can determine that it doesn’t use any static help we might include in regard to the parameter(s).

Function Check-ParameterCount {
    [CmdletBinding()]
    Param (
        [Parameter()]
        [string]$Param01,

        [Parameter()]
        [string]$Param02
    )

    $ParameterCount = (Get-Help -Name Check-ParameterCount).Parameters.Parameter.Count
    "There are $ParameterCount possible parameter(s) in this function not including the common parameters."
}
PS > Check-ParameterCount
There are 2 possible parameter(s) in this function.

That was it. Again, let me know if there’s a better way.

Update: I had a thought. Because my function uses the CmdletBinding attribute, it’s possible that my function can have more than the number of parameters returned by Get-Help. Therefore, I’ve only slightly modified the above strings my function returns. It was “There are $ParameterCount possible parameter(s) in this function.”, and now it’s “There are $ParameterCount possible parameter(s) in this function not including the common parameters.” Now, it indicates it returns X number of parameters, not to include the command parameters.

PS > Check-ParameterCount
There are 2 possible parameter(s) in this function not including the common parameters.