This is an open plea to Microsoft for the creation of the internal position of PowerShell Czar.
There is a PowerShell UserVoice suggestion to open source the AD module that is quickly accumulating votes. https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/13350033-open-source-the-activedirectory-powershell-module
This is not users requesting a feature or a fix. This is exasperated users giving up hope that Microsoft will make basic improvements to the product.
There are too many teams at Microsoft that years ago came out with a reasonable (for the time) first version of the PowerShell module for their product, but have never followed up with v2. When they release a new version of their product, they make some minor changes to the PowerShell module that are related to new features in the core product. But they don’t understand that the PowerShell module is an integral part of their product, deserving of and requiring the same continuous improvement as the rest of their product, and it never matures past the level of barely good enough for a first release.
It has been ten years now, and too many teams at Microsoft have demonstrated that left to their own devices, they are not willing or able to produce the quality of PowerShell integration that we need.
Microsoft needs to create a PowerShell Czar. They can, of course, replace that silly title with one of the standard Microsoft silly titles, but the role would be the same.
The Czar would have the power to write and enforce PowerShell standards across the organization. The Czar would prevent releases from releasing if the PowerShell isn’t ready. The Czar would require teams to fill gaps in the PowerShell interface. The Czar would prevent desktop teams from locking in a pre-release version of PowerShell. The Czar would prevent teams from using non-standard parameter names and cmdlet names that are so long they wrap around the screen. The Czar would require implementations that are intuitive to PowerShell scripters, rather than to product architects. The Czar would require all MSDN articles about .Net objects to have PowerShell examples. The Czar would require MSDN articles about PowerShell .Net object be as complete as articles about other .Net objects. The Czar would require fixes to .Net objects that break PowerShell functionality that depends on them.
If Microsoft has another, less authoritarian way of accomplishing the same goals, fine, do it that way. But the current way is not working. This needs to be fixed. Microsoft, please make it happen.
Tim Curwick's PowerShell blog | Tips and tricks and tools and techniques | Explanations and explorations
Thursday, April 14, 2016
Monday, March 28, 2016
Sorting IP addresses in PowerShell, part 1, IPv4
Sorting IP v4 addresses is a pain. If they are strings, they sort typographically rather than numerically.
If they are [ipaddress] objects, they do the same thing. The [ipaddress] does not have the built in methods that PowerShell would use to sort it, so PowerShell converts it to a string, and then sorts it typographically.
I have in the past come up with a variety of complex ways to do it. Here’s one.
There is an easier way
There is an object which can look like an IP address, which needs to be sorted like an IP address, and whose creators had the foresight to endow it with a .CompareTo() method, which is what PowerShell uses when it sorts things. The [System.Version] object is used to represent file and application versions, and we can leverage it to sort IP addresses simply. We sort on a custom calculation, converting the IP addresses to version objects. The conversion is just for sorting purposes. The output is the original input objects.
The System namespace is the default namespace PowerShell searches for things, so we can leave that out and write it more simply.
Or if we want to go the other way, and avoid aliases and positional parameters, we can say it this way.
$IPAddresses = @(
'10.11.12.13' '10.11.102.3' '10.11.10.26' '10.11.10.252' ) $IPAddresses | Sort |
10.11.10.252
10.11.10.26 10.11.102.3 10.11.12.13 |
If they are [ipaddress] objects, they do the same thing. The [ipaddress] does not have the built in methods that PowerShell would use to sort it, so PowerShell converts it to a string, and then sorts it typographically.
$IPAddresses = @(
[System.Net.IPAddress]'10.11.12.13' [System.Net.IPAddress]'10.11.102.3' [System.Net.IPAddress]'10.11.10.26' [System.Net.IPAddress]'10.11.10.252' ) $IPAddresses | Sort | Select IPAddressToString |
IPAddressToString
----------------- 10.11.10.252 10.11.10.26 10.11.102.3 10.11.12.13 |
I have in the past come up with a variety of complex ways to do it. Here’s one.
# Function to convert dotted decimal notation to integer64 (e.g. - "255.255.255.0" to 4294967040)
function ConvertDottedDecimalToInt64 ( $DottedDecimal ) { $DecimalParts = $DottedDecimal.Split( "." ) $Result = [int64]0 0..3 | ForEach { $Result += [int64]$DecimalParts[$_] * [math]::pow( 256, 3 - $_ ) } return $Result } $IPAddresses = @( '10.11.12.13' '10.11.102.3' '10.11.10.26' '10.11.10.252' ) $IPAddresses | Sort { ConvertDottedDecimalToInt64 $_ } |
10.11.10.26
10.11.10.252 10.11.12.13 10.11.102.3 |
There is an easier way
There is an object which can look like an IP address, which needs to be sorted like an IP address, and whose creators had the foresight to endow it with a .CompareTo() method, which is what PowerShell uses when it sorts things. The [System.Version] object is used to represent file and application versions, and we can leverage it to sort IP addresses simply. We sort on a custom calculation, converting the IP addresses to version objects. The conversion is just for sorting purposes. The output is the original input objects.
$IPAddresses = @(
'10.11.12.13' '10.11.102.3' '10.11.10.26' '10.11.10.252' ) $IPAddresses | Sort { [System.Version]$_ } |
10.11.10.26
10.11.10.252 10.11.12.13 10.11.102.3 |
The System namespace is the default namespace PowerShell searches for things, so we can leave that out and write it more simply.
$IPAddresses | Sort { [version]$_ }
|
Or if we want to go the other way, and avoid aliases and positional parameters, we can say it this way.
$IPAddresses | Sort-Object -Property { [System.Version]$_ }
|
Wednesday, February 17, 2016
Codependent simultaneous variable updates in PowerShell
I recently rediscovered the comma. There is always something more to learn in PowerShell. And not just the new big things. There are always little things that get missed or forgotten. I think I may have known about commas at one time, but did not find them of immediate use, so I forgot about them.
Specifically, I was reading an advance copy of chapter 1 of PowerShell in Action, Third Edition, by Bruce Payette and Richard Siddaway, and read that you can assign values to multiple variables at the same time in a single line by separating both the variable names and the values by commas.
So instead of this:
You can do this:
Most of the time, you would never do that. The first syntax is much more clear.
But there are two situations where this is useful. One is when a command naturally results in the multiple values you are looking to assign.
Instead of this:
You can do this:
Where it becomes really useful, is when you have to make simultaneous codependent changes to your values.
For example, if you need to swap two values, instead of this
You can do this:
Or let’s say you are working on a script for calculating Mandelbrot’s set. You will have a function that sets complex number Z to Z squared plus C. As a complex number, Z has both a real component and an imaginary component. In your calculation, you need to use the old value of the real component to calculate the new value of the imaginary component, and you need the old value of the imaginary component to calculate the new value of the real component.
Instead of this:
You can do this:
(And yes, I know there are .Net object that will let you work with complex numbers even more easily than that, but this is the conceit of the example, so deal with it.)
Specifically, I was reading an advance copy of chapter 1 of PowerShell in Action, Third Edition, by Bruce Payette and Richard Siddaway, and read that you can assign values to multiple variables at the same time in a single line by separating both the variable names and the values by commas.
So instead of this:
|
$A = 1
$B = 2 |
You can do this:
|
$A, $B = 1, 2
|
Most of the time, you would never do that. The first syntax is much more clear.
But there are two situations where this is useful. One is when a command naturally results in the multiple values you are looking to assign.
Instead of this:
|
$FQDN = "Server1.HQ.contoso.com"
$FQDNArray = $FQDN.Split( ".", 3 ) $ComputerName = $FQDNArray[0] $ChildDomain = $FQDNArray[1] $RootDomain = $FQDN[2] |
You can do this:
|
$FQDN = "Server1.HQ.contoso.com"
$ComputerName, $ChildDomain, $RootDomain = $FQDN.Split( ".", 3 ) |
Where it becomes really useful, is when you have to make simultaneous codependent changes to your values.
For example, if you need to swap two values, instead of this
|
$Temp = $A
$A = $B $B = $A |
You can do this:
|
$A, $B = $B, $A
|
Or let’s say you are working on a script for calculating Mandelbrot’s set. You will have a function that sets complex number Z to Z squared plus C. As a complex number, Z has both a real component and an imaginary component. In your calculation, you need to use the old value of the real component to calculate the new value of the imaginary component, and you need the old value of the imaginary component to calculate the new value of the real component.
Instead of this:
|
$Newr = $Zr * $Zr - $Zi * $Zi + $Cr
$Newi = 2 * $Zr * $Zi + $Ci $Zr = $Newr $Zi = $Newi |
You can do this:
|
$Zr, $Zi = ( $Zr * $Zr - $Zi * $Zi + $Cr ), ( 2 * $Zr * $Zi + $Ci )
|
(And yes, I know there are .Net object that will let you work with complex numbers even more easily than that, but this is the conceit of the example, so deal with it.)
Subscribe to:
Posts (Atom)