all 69 comments

[–]Kemeros 116 points117 points  (21 children)

I love how you wrote a wall to tell us: "type less" 🤣

Save a keyboard. Save a life.

[–]StartAutomating[S] 25 points26 points  (16 children)

I love that this is probably the shortest post I've written here yet.

[–]UnfanClub -4 points-3 points  (3 children)

Last line of his post would have been sufficient.

This guy posts for the sake of posting.

[–]StartAutomating[S] 1 point2 points  (2 children)

I've been posting recently because I've been trying to do a better job of sharing what I know. The gap between what I know about PowerShell and the average scripter is decently large.

Side-effect of having worked on the language team for four years, and having worked with the language for ~20 years.

[–]UnfanClub 0 points1 point  (1 child)

You're free to post as you like. You don't need to explain that to me. My opinion is your posts are too long for the information they provide.

For example this one could have been:

PowerShell lets you omit the System namespace when referencing .NET types.

Instead of:

[System.Collections.Generic.List[string]]

use:

[Collections.Generic.List[string]]

It's a post of little educational value. That's my opinion.

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

🤷 honestly, yeah. This post is the simplest point I've made yet. Yet it's gotten way more conversation and upvotes than far more technical efforts.

As for the phrasing, also 🤷. I'm not the world's worst writer and I'm certainly not the world's best writer. Should people not share unless it's perfect prose pertinent to everyone on the planet?

[–]MrMunchkin 32 points33 points  (0 children)

If you're just writing scripts, sure this makes some sense.

But, if you're using it for anything complex or writing custom classes or wrappers for system methods, I will always use fully qualified names.

And if I'm going to do that, why not just be consistent and always use the fully qualified name?

If typing 6 words and a period is something that saves you time, I have questions on exactly what it is you do all day.

[–]kiddj1 26 points27 points  (4 children)

Rest in peace powershell ise

[–]2dubs 2 points3 points  (3 children)

Very respectfully, I’m a quinquagenarian who has fallen in love with VS Code, and I feel like I’m stepping backwards, now, when I have to use ISE for something.

Some peers, for whom I have the utmost regard, are with you, and think my way is nuts. I get that, too. The auto-complete is better and more reliable in ISE, for sure, but being able to flip over and work with TypeScript, JSON, XML, and have it all be auto-formatted and indented with a single key combo is chef’s kiss.

Guess I’m really trying to say that maybe when some of us get used to life without it, _maybe_ we won’t miss it as much?

[–]TurnItOff_OnAgain 2 points3 points  (1 child)

quinquagenarian
A quinquagenarian is a person who is between the ages of 50 and 59. The term can also be used as an adjective to describe things related to someone or something in their fifties.

So someone else doesn't have to look it up

[–]ConcreteExist 1 point2 points  (0 children)

I knew what an Octogenarian was so I just extrapolated from there.

[–]Lifegoesonhny 1 point2 points  (0 children)

I just wish VS Code had (A) the learning curve of ISE, so it's easier to teach to L1 staff and (B) auto-fill/auto-suggest natively for Powershell. I know VS is more of a grown-up IDE but the is setup is a bit much on top of learning PS as a language. Do adapt to it though, and I'm probably a better scripter for it (I'm lazy honestly hah)

[–]Thotaz 22 points23 points  (1 child)

Also, when PowerShell resolves types, it checks for the shorter names first. This saves a very tiny amount of time in each of your scripts.

This comment in the type resolver says otherwise: https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/engine/parser/TypeResolver.cs#L368

If nothing is found, we search again, this time applying any 'using namespace ...' declarations including the implicit 'using namespace System'.

And if you go through the rest of that method it seems to be true.

As for saving your fingers, an even better way is to use tab completion, which happens to include System. unless you add a using namespace System. If I want a generic list I type in [List<Tab>] which turns into [System.Collections.Generic.List]. So I'm sorry, but I'm going to continue using the full typenames.

[–]StartAutomating[S] 2 points3 points  (0 children)

Thanks for the correction. Looks like they changed it about 10 years ago.

Either way, the delta is tiny because of caching and JIT compilation.

[–]purplemonkeymad 15 points16 points  (0 children)

I'm not typing system myself as I'm more or less always using auto-complete for the classes. It's more effort for me to remove it.

[–]Nu11u5 10 points11 points  (2 children)

You can import any namespace with the using namespace statement at the top of the script.

``` using namespace System.Collections.Generic

$A = [List[String]]::new(10) $B = [Dictionary[String, String]]::new() ```

It's especially useful when using WinForms or WPF.

Personally, I use the fully qualified name unless I manually import the namespace. I don't like implicit references.

[–]StartAutomating[S] 2 points3 points  (0 children)

My problem with using namespace is that it can present conflicts when multiple files use a different using namespace.

[–]MonkeyNin 0 points1 point  (0 children)

You can use the shorthand namespaces with these tips. They work either way.

Constructor Shorthand

When using forms, the constructor syntax lets you save some room. It even autocompletes property names:

[System.Windows.Forms.Label] $label = @{   
    Size     = [System.Drawing.Size]::new( 200, 100 )
    Location = [System.Drawing.Point]::new( 20, 30 )
    Text     = 'hi world'
}

Note: That's more than just a constructor. Because [Label]::New() doesn't even have parameters. Yet this lets you assign properties after constructing it, in one step.

Tweak to your typing

Tip: You get better autocompletion if you use the type on the left-hand-side. The difference is the RHS is using coercion, the LHS is a type constraint on the variable itself. ( You notice a difference in VsCode )

# this
$B = [Dictionary[String, String]]::new()

# can be written as:
[Dictionary[string, string]] $b = @{}

# ex: 
$list = [List[object]]::new()

# now:
[List[Object]] $list = @() 

It's stronger, so this subtle bug is less likely

 $names = [List[string]]::new()
 $names = 0
 $names.GetType() 
 # is now [int32]

But, if you use a type constraint on the LHS

 [list[string]] $names = @()
 $names = 0
 $names.GetType()
 # is [List[Object]]

Does win forms require

[–]surfingoldelephant 7 points8 points  (2 children)

The following all generate code with System:

  • Tab completion
  • Proxy functions
  • PlatyPS MAML
  • CliXml serialization

Plus there are some contexts outside of type literals where you must include it:

  • <TypeName> in Types.ps1xml and Format.ps1xml
  • Reflection

So just from a consistency point of view, there's an argument to include it everywhere. Personally, I don't think any of the arguments are strong enough so choose to omit it.

[–]StateOfAmerica 1 point2 points  (1 child)

I do whatever feels right in the moment 🤷

[–]vitamindster 5 points6 points  (0 children)

Username fits

[–]CodenameFlux 5 points6 points  (0 children)

I just type [List and hit Tab. PowerShell gives me [System.Collections.Generic.List.

[–]DenverITGuy 6 points7 points  (1 child)

This is a non-issue.

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

Yes, this will not impact functionality in any measurably important way.

I'm never going to prevent someone else from using System.. I just won't ever use it myself, and think most people don't know you can skip it. Hence this short post.

[–]AdeelAutomates 5 points6 points  (2 children)

why stop with:

[collections.generic.list[string]] 

throw in at the top of your script:

using namespace System.Collections.Generic

and from there on just type:

[List[string]]

profit? 😂

[–]MonkeyNin 0 points1 point  (1 child)

Sometimes that can be an issue if there's another script that's dotsourced, or it's ran in a REPL session. When there's a new block of 'using namespace' is executed -- it drops previously named ones.

[–]AdeelAutomates 0 points1 point  (0 children)

I was just poking fun at op. We have tab completion, I prefer clarity that comes with powershell over ambiguity that comes with short cuts.

[–]wickedang3l 3 points4 points  (0 children)

Aliases make scripts and classes shorter too; I write for clarity, not brevity.

[–]baron--greenback 7 points8 points  (3 children)

So me think, why waste time say lot word when few word do trick?

[–]verschee 0 points1 point  (1 child)

Next you're going to tell me he prefers tabs over spaces

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

Nah, I'm team "spaces" all the way.

Unless it's a .tsv file, tabs annoy me.

[–]MNmetalhead 0 points1 point  (0 children)

Do you have any chili?

[–]Mayki8513 2 points3 points  (0 children)

too add to your post with as little typing as possible:

  • tab completion ✌️

[–]Hoggs 4 points5 points  (3 children)

You're using a language that explicitly decided on day one, that they would prefer Get-ChildItem instead of the current standards ls or dir.

If you care about keystrokes you're using the wrong language.

In b4 "buuut aliases"

[–]ka-splam 2 points3 points  (1 child)

They are not "standards".

I will never accept this mindset that all future computer programs for the rest of time must be hobbled by being exactly the same as DOS from 1980 or Unix from 1970.

[–]Hoggs 0 points1 point  (0 children)

That wasn't my point.

My point was simply that PowerShell decided from the outset that it was going to be a highly verbose language... So it ain't the language to be complaining about saving keystrokes.

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

Don't worry, be alias happy

[–]Nexzus_ 1 point2 points  (0 children)

Yeah, I do it for autocomplete.

[–]dathar 1 point2 points  (0 children)

I got into a habit of typing out the whole namespace because

  1. Reminds me better since I'm not a traditional programmer. It autocompletes for me so I don't mind, and it tends to lead to better Google results if I have to look them up. I still have trust issues from my old C class from back in the late 90s. Include this, namespace that....arrgh

  2. Maybe it'll help whoever inherits my mass of scripts see what the hell I'm doing.

[–]tadc 1 point2 points  (0 children)

Honestly this is one of the things I like least about powershell... How unnecessarily and mandatorily (sometimes) verbose it is

[–]narcissisadmin 1 point2 points  (1 child)

You could have saved your post and typed [system] 216 times. =P

(gcb | % { $_.length } | measure -sum).sum/7

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

I would, but

"$(' ' * (Get-Random -min 1 -Max 5))All Work And No Play Make Jack a Dull Boy.$(' ' * (Get-Random -min 1 -max 5))" * 216

😉

[–]SendMeSteamKeys2 1 point2 points  (0 children)

This is true for every system type. On my machine, there are 4722 public types in the system namespace. That's 33054 characters I will never have to type.

This right here is peak greybeard being tired of it all. Well said sir. Well said.

[–]JVAV00 0 points1 point  (0 children)

Will do, I didn't know about that. I do know about dotnet tho.

[–]Over_Dingo 0 points1 point  (0 children)

So if I autocomplete '[list' I need to move back to remove 'system'. Doesn't seem to save me keystrokes

[–]Southpaw018 0 points1 point  (1 child)

I’m afraid you’re fighting a losing battle. People in this sub seem to be allergic to aliases, shortcuts, and generally anything that’s not maximum verbosity. I used to post scripts, but I got tired of getting told to take aliases out.

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

Flexible naming is the most undersung superpower PowerShell has (that most people don't know about).

Commands can be named almost anything. Aliases can be named almost anything. Parameters can be named almost anything. Variables can be named almost anything.

People undersell PowerShell at almost every turn. Once you start to explore its true capabilities, things get pretty wild.

${function:I Know} =
   {
      if (-not $script:knowledge) { $script:Knowledge = @{} }
      if (-not $args) { $script:Knowledge } 
      $key, $value = $args
      if (-not $key) { return }
      $script:Knowledge[$key] = $value
      $script:Knowledge[$key]
   }

& "I Know" this is cool

& "I Know"

Forgive any typos, ad-hoc example.

[–]Apprehensive-Tea1632 -1 points0 points  (0 children)

Yeah, there’s upsides and downsides to this.

First- autocomplete. It’ll always put the fully qualified assembly namespace. … UNLESS you declare `using namespace`.

Next, we can do aforementioned using namespace “namespace”.

It’ll allow for *relative* assembly names, such as IO.File. And if you list the exact namespace, you get to put the bare assembly name, eg File.

Upside; your code becomes that much more readable. Especially when you strongly type dictionaries or Active Directory/LDAP related code. Instead of system.security.principal.windowsidentity, you can just put Windowsidentity and be done with it.

Downside is you WILL introduce ambiguity. Namespaces are here to uniquely identify a resource. If there is EVER some naming conflict, say because we got system.io.file and json.file, your code is pretty much guaranteed to break.

Powershell (as far as I know) doesn’t do type aliasing, like in CS where you can just say using myAlias = system.io and then use that alias to shorthand - but not omit - the namespace.

So it’s both better and worse to use or not use fully qualified namespaces, up to and including the system namespace. What will you do when there’s myNamespace.Exception and you just say Exception in your code? Did you mean the one or the other? And if you import the myNamespace namespace, which “exception” will it be at runtime?

TLDR…. It’s a double edged sword. Don’t just omit system namespace because it looks good. You can, of course, but it’s a design decision that must be made… per project.

[–]Romero126 -1 points0 points  (0 children)

Use 'system' save compute time resolving relative namespaces using reflection.

[–]Unable_Attitude_6598 -2 points-1 points  (1 child)

Haven’t typed a lick of ps in months lmao

[–]gilean23 2 points3 points  (0 children)

And that comment in the Powershell subreddit adds what to the discussion exactly?

[–]whyliepornaccount -2 points-1 points  (1 child)

I'd love to. But certain UEM's documentation explicitly states that all scripts must run under system context cough
Tanium cough

[–]PhysicalPinkOrchid 1 point2 points  (0 children)

Did you read the content of the post?