I was trying to teach my troops to use PS instead of the Windows Server GUI. My goal for the series of lessons was to show them how to find their way without memorizing a hundred modules' cmdlets, which is how I've largely done it, and because our job is to raise the network from the ground up. While standing up a fresh WS2012R2 server, I mentioned automatic variables, especially Boolean values, and proceeded to run through an example (turning off IPv6 using Set-NetAdapterBinding) and, of course, its exception (disabling Windows Firewall). What I don't understand is, 'why' doesn't Set-NetFirewallProfile take a Boolean automatic variable as an argument for the -Enabled parameter, but most other cmdlets do? Please point me in some direction?
PS C:\> Set-NetFirewallProfile * -Enabled $False Set-NetFirewallProfile : Cannot process argument transformation on parameter 'Enabled'. Cannot convert value "False" to type "Microsoft.PowerShell.Cmdletization.GeneratedTypes.NetSecurity.GpoBoolean". Error: "Invalid cast from 'System.Boolean' to 'Microsoft.PowerShell.Cmdletization.GeneratedTypes.NetSecurity.GpoBoolean'." At line:1 char:35 + Set-NetFirewallProfile * -Enabled $False + ~~~~~~ + CategoryInfo : InvalidData: (:) [Set-NetFirewallProfile], ParameterBindingArgumentTransformationException + FullyQualifiedErrorId : ParameterArgumentTransformationError,Set-NetFirewallProfile PS C:\> Set-NetFirewallProfile * -Enabled False PS C:\>PS C:\> Stop-Transcript ********************** Windows PowerShell transcript end End time: 20180218110109 **********************
Also, why is the $false argument case sensitive?
PS C:\> PS C:\> Set-NetAdapterBinding -ifAlias eth* -ComponentID ms_tcpip6 -Enabled $False Get-Process : A positional parameter cannot be found that accepts argument 'Set-NetAdapterBinding'. At line:1 char:1 + PS C:\> Set-NetAdapterBinding -ifAlias eth* -ComponentID ms_tcpip6 -E ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Get-Process], ParameterBindingException + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetProcessCommand PS C:\> Set-NetAdapterBinding -ifAlias 'eth*' -ComponentID ms_tcpip6 -Enabled $false PS C:\> PS C:\> Set-NetAdapterBinding -ifAlias 'eth*' -ComponentID ms_tcpip6 -Enabled $False Get-Process : A positional parameter cannot be found that accepts argument 'Set-NetAdapterBinding'. At line:1 char:1 + PS C:\> Set-NetAdapterBinding -ifAlias 'eth*' -ComponentID ms_tcpip6 ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Get-Process], ParameterBindingException + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetProcessCommand
Well, that has never really been true. I have been in IT for 4+ decades (an educator for half that time) and counting, and using MS stack since DOSv2/Win1x (ITPro, Dev, etc). As they moved forward with there wares, I have encountered more than my share of case sensitive items, especially as .Net hit the world. With all the cross platform stuff MS is now doing, the adage needs to be changed to:
In your $true / $false thing. If you type any built-in variable, or any cmdlet in a different case than is expected, sometimes PoSH will coerce it, but not always. At least that been my observation. If you want to be sure you are doing the right thing with a variable, function, cmdlet or alias naming construct. Type it, click anywhere in that variable, function, cmdlet, or alias string and tap the tab key. It will covert that string to the expected case / style.
So, you are going to see this more, IMHO, because of their cross platform direction.
As for the built-in variables, argument naming. You have to used them as they are defined. Don't get creative. Thye are desinged the way they are designed. YOu may not care for that design decision, but it is what it is.
All things are explained in the help file of each of the cmdlets relative to you query and in teaching, it's an absolute must that you hammer in the use of the help files. Showing that help for X & Y at every turn vs just showing the cmdlet in use.
As an educator for many years, I learned this lesson early on, and in every session I deliver, the first topic covered is how to find built-in help and help yourself. Starting with keeping this in front of students for the entire class.
# Get parameters, examples, full and Online help for a cmdlet or function (Get-Command -Name Set-NetFirewallProfile).Parameters Get-help -Name Set-NetFirewallProfile -Examples Get-help -Name Set-NetFirewallProfile -Full Get-help -Name Set-NetFirewallProfile -Online Set-NetFirewallProfile | Get-Member Get-Help about_* # All Help topics locations explorer "$pshome\$($Host.CurrentCulture.Name)" Get-NetFirewallProfile -Name Domain | Get-Member
If they have a question, and they have not looked at the above info, I direct them there. If they don't find what they need to satisfy their query there, then we dig further. Education, is not just delivering, How To's, it is also about How Come and why.
Living with the philosophy, that, relative to IT, there is most likely not a single question which can be asked, in recent years; which has not already been asked and answered in one form or the other; via a book, article, class, friend, co-worker, well, internet-wide. Now, there may never be in a single source / location, so, you have to keep digging, the greater portion of the time to get all the pieces to put together. Avoid guessing/speculation/assumptions/should do thoughts, until you have absolutely exhausted all possible knowledge avenues. Any product is a philosophy of 'Supposed to do', that is, what it is documented to do, vs 'Should do / What one thinks it should do.' That should do stuff, is based what they may have learned before, other experiences, etc. Yet, that does not matter. Learn and use the 'Supposed to do', then mess with the 'let's see if I can make it do X or Y, because I think it should do it they way I think it should.'
Now, about boolean, switch, arugment, query.
Going back to my help commnet above and looking at the two cmdlets in question, it will be obvious what they difference in the boolean expectation is. Again, one may not like it, but, you have to use it the way it is defined.
This is a true string property use case and not a built-in variable.
This is a binary 1 or 0 surfaced via the variable name. Notice the type difference for that boolean, vs the later.
Noted from the web....
Then there is this series as well
You must be logged in to reply to this topic.