Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Simple PowerShell things allowing you to dig a bit deeper than usual (github.com/gtworek)
127 points by keepamovin on Aug 22, 2023 | hide | past | favorite | 58 comments


Folks I may have misunderstood what this is. Thought it was a bunch of PowerShell bits, but on closer inspection there seems to be a lot of c files and exes of somewhat dubious purpose? I don't know. Anyway, sorry for the seemingly bogus (in stated purpose at least) repo. A PowerShell repo of snippets would be a good thing!


The title is a bit confusing if you aren't familiar with the needs the author is probably trying to get.

They're likely a sysadmin trying very hard to get around a lot of limitations Microsoft has on their out of box toolsets and to avoid home-rolling a lot of solutions in more challenging languages.

So a combination of C files, executables, and PS scripts is pretty normal for such an environment. The C/.exes are likely because there are usually pretty obvious walls in Powershell once you're reaching the limit of what PS is meant to do; if most of your code is just .NET, probably you should be writing a small .NET app instead of trying to do it through powershell; given that it's not always easy to just execute a PS script on end-user environments depending on the GPOs and other security items, probably the author has just written some very common workflows that were too annoying to do manually, not worth the effort for a fully functional program, but needed more than what Windows returns normally to Powershell.

I'd say the author is on the far end of the Powershell User spectrum, as the tooling is pretty good, and it's clear from the use-cases they list that they are really trying to administrate their Windows boxes very personally but without having to click around the UI a ton. Many of the scripts are just to get around windows' permissioning and access control


As a side note, you can literally write a C# program and run it inside PowerShell without installing the normal .NET toolchain. Add-Type can accept a string with C# source code and it'll build on-the-fly and load it into your PowerShell environment. And from the C# code you can P/Invoke C functions if you need.

Once you've loaded it up, you can use it directly from PowerShell. I've done this in a pinch and then wrapped it up in a normal PowerShell cmdlet to do things that weren't available from PowerShell otherwise and without needing a .NET build workflow, without needing to store .DLLs, etc. In OP's situation that's what I'd be doing instead of building .DLLs.

https://learn.microsoft.com/en-us/powershell/module/microsof...


I love on Hacker News you can start off thinking think you’re right, and then realize your wrong, but then later on you discover that actually you were right in the first place, when another level of expert commenter has been unlocked by the topic. Haha! :)


I only discovered Powershell recently, and it's impressed me how "batteries-included" it is. Like, I can access the GitHub API, download the latest release of a program, and decompress it, with progress indicators shown throughout, all without importing a library. At times, it feels more Pythonic than Python.

But jeez, the syntax. There's a lot to say, but the worst is that I'm never sure where I need to place parentheses. By making brackets in function calls optional, it just makes you end up writing Lisp-like code when the arguments are also function calls or arrays. You are forced to write parenthesized function calls anyways when invoking .NET commands, so they might as well make it universal instead of this chimerical compromise. It's a similar story with quotation marks around strings.

But it speaks to the strengths of the language that I still enjoy writing it anyways.


Function calls don't need parens because it's an interactive shell, and nobody writes Bash or Command prompt lines like:

    user@server$ grep('word', 'file.txt')

    C:\ > notepad.exe()
And if they did make that the requirement it would be an instant dealbreaker for a lot of people coming from other shells. It is indeed a similar story with quotation marks around strings, in that you don't want to have to write:

    user@server$ grep 'word' 'file.txt'
when you could write

    user@server$ grep word file.txt

If the parser can tell from the context that the next token should be a string, it will read it as a string. If it can't tell, and the next token might be a command but you want it to be a string, then you have to quote it. If there's a space e.g. in the file path and you want it to be read as a single token, you have to quote it. Always quoting won't break anything, it's just unnecessary.


I've often gotten caught out using commas to separate arguments like most other scripting languages ever. One of those things you need to remember when writing Powershell scripts!


Can you give an example of where/how? I imagine you don't get caught out writing Bash scripts like:

    grep -e,-i,'\bneedle\b',file.txt | cut -F,2,-d,':'
Because that's so contextually distinct from Python/JavaScript/Ruby; in shells (and APL, J, LISPs), arrays of commands and their arguments are space separated rather than comma separated. Similar in PowerShell, where it looks like shell it tends to work like shell:

    get-childitem -Path c:\ -Filter *.txt -Force
Where it looks like scripting language it tends to work like one:

    $host.ui.WriteLine('Green', 'Yellow', 'Hi')


With functions

  function Get-Something {
    Param (
      [Parameter(Mandatory=$true, Position=0)]
      [string] $Name,
      [Parameter(Mandatory=$true, Position=1)]
      [int] $Id
    )
    # Write the output to the console
    Write-Output "Name: $Name, Id: $Id"
  }

  Get-Something "Alice" 42
If you were to call

  Get-Something("Alice", 42)
It would pass "Alice", 42 to the first parameter.

You can use named parameters to get round this, e.g.

  Get-Something -Name "Alice" -Id 42
Still a bit of a gotcha!


Powershell is underrated and I actually prefer it over bash but indeed the syntax can be a slog sometimes. I used it a lot but I never felt I was “fluent” and found myself usually often needing the docs for even basic syntax (for loop, function params, etc.) Also in my experience I found some of the limitations surprising, having to call .NET methods was not uncommon for me. Regardless I’m happy to never write a batch script for the rest of my life, powershell is definitely an upgrade.


I really do not see powershell as a bash, zsh, fish, ... shell equivalent. It is more inline with perl, python, php, ... scripting languages. One thing I really dislike about powershell development is default aliasing such as using curl to actually call Invoke-WebRequest. This was such bad taste and disrespectful to the actual application and their developers that make a really good library and tool. Windows even now comes with curl.exe in C:\Windows\System32.


> One thing I really dislike about powershell development is default aliasing such as using curl to actually call Invoke-WebRequest.

Hasn't been a thing for a while now.


While it's true that it's no longer aliased in PowerShell 7, the currently shipping version of Windows PowerShell included in Windows 11 still aliases it to this day. If you intend to be portable across both versions, you still have to use "curl.exe" to get the real curl.


My main use for llms has been to finally start making power shell scripts


Heh, so much so. I'll have gpt make a series of loops and evaluators and then come back and put the my logic in the placeholders.

The other thing I find is by thinking out the process of what I need and communicating to the LLM is I tend to make better scripts that have more functionality since I'm thinking about what I want done, and not thinking about just getting the syntax correct.


It is great for doing something like 'write a script that recursively goes through all the directories and finds pictures which were taken between <date> and <date> and copy them to <directory> then sort them in subdirectories by month and day.'

So much tedium is now easy if I can remember 'powershell can do it, and GPT can write it for me'.


Agreed. Coming from C# and from traditional Unix shells, PowerShell feels like it was made competently but with no aesthetic taste whatsoever. It's got a syntax only a mother could love. But its flexibility and usefulness can't be denied. It's just... ugly.


Just been trying Nushell and comparing it to Powershell, and you can clearly feel the inspiration, except that everything is a table or a list of record instead of their own special objects.

It makes the syntax quite a lot cleaner, albeit sometimes less convenient, but more coherent.

With Powershell Core being the same on Windows, Linux and Mac OS, I find it much better to write small scripts with it, and more portable too. Never have to find out that the options to sed or another utility isn’t the same on macOS vs Linux for example.


A few days ago I've tried to set four aliases to some files with calling a simple function. I took about an hour with help of chatgpt and still I'm not sure how things works.


> I only discovered Powershell recently, and it's impressed me how "batteries-included" it is.

Meh. Powershell, like most things windows, is just a dumbed down version of its unix equivalent to cater to its 'lower-skilled' user base. The best thing about powershell is its documentation and help section. It's far more 'detailed' and far more examples than its unix counterpart. How many times do you just wish a man page just had an example that you tinker with to get what you want? With powershell, you get that. Another thing going for powershell on windows ecosystem is that microsoft is tying powershell with their servers to make administration simpler and easier.

But powershell certainly isn't python or perl.


> "How many times do you just wish a man page just had an example that you tinker with to get what you want? With powershell, you get that"

Two sentences ago you said helping people was dumbing down for low skill users. Hmm.

> "Another thing going for powershell on windows ecosystem is that microsoft is tying powershell with their servers to make administration simpler and easier."

They have been untying PowerShell from their servers for 7 years. PowerShell current version doesn't ship with Windows and does run on macOS and Linux.

> But powershell certainly isn't python

PowerShell has a good interactive shell, better/more convenient introspection/reflection, integrates more thoroughly with its underlying language (C#), has more humane defaults (case insensitivity).


I used to write a lot of bash and fish and I find Powershell has a much higher skill ceiling.


[flagged]


I read that as "I don't know what a skill ceiling is".


This seems great. On a side note, I've been trying to learn powershell lately since I'm stuck on Windows at work. I'm not allowed to download utilities for powershell, and it feels anemic to me compared to a unix shell. An example of this is when I wanted to work with Json using ConvertTo-Json and the output kept getting mangled even though it was changing the right fields. Eventually I gave up and wrote a node script and just called it from my ps script. Is there a solution for making powershell actually enjoyable to use?


Powershell does take a while to become fun. Key thing (I assume you know this?) is that while bash pipes a string-stream, powershell pipes a stream of structured objects. This is powerfull but also quite confusing sometimes.

The other key thing is that Powershell has straight access to the whole .NET framework (or whatever its called these days) except you've gotta switch to .CallSomeMethod(with,brackets) syntax for that.

This list of common Gotchas on SO was useful to me: https://stackoverflow.com/a/69644807/22194

Powershell is quite good at working with CSV: Import-CSV, Export-CSV, Where-Object, Select-Object, Sort-Object, Group-Object etc become quite handy when used together.


I've been writing powershell for 5 years and I'd rather slice my balls up with glass and dive into the red sea. How much longer before it becomes fun?


At least another 5 years I'm afraid


My poor balls


Windows PowerShell targets the old .NET Framework, which is Windows-dependent. Modern PowerShell targets .NET [Core] and is cross-platform. Also, it's not true that you need to use "CallMethod;" PowerShell can invoke methods with syntax nearly identical to C#'s.


edited my comment above for clarity - I didn't mean literally CallMethod, I meant that normally Powershell uses 'shell' syntax where parameters are separated by spaces

Do-Something withthisfile.txt -AdditionalParam 23

But if you're calling a .NET method you switch to C# syntax with brackets and commas:

$str.Trim('-')

I mean thats kindof obvious but its one of the many things that makes Powershell's learning curve a little steeper. But hey we can always just google it which is par for the course anyway nowadays


Not sure, but I think the above commentor was meaning to tell that powershell supports .NET reflection.

That is, while you can call .NET methods on objects like:

$Object.SomeMethod('arguments')

You can also do:

[Namespace.ClassName]::SomeMethod('arguments')

And your Powershell scripts can even save you a lot of typing with the ```using``` function of Powershell to load namespaces: https://learn.microsoft.com/en-us/powershell/module/microsof...

Edit: As to why you would want to do this, usually it's because you want to do some scripting but you need to pull data out of some .NET application or out of Windows and there isn't a fully fleshed out cmdlet built for it. In a pinch, you can usually just use reflection to get it. For example, I needed to pull data from a Shared Outlook calendar that not everyone had access to and then do some date-math to share a time-sensitive schedule with a team living in quite a few timezones. Reflection to load the necessary Outlook and MSExchange elements, then the rest in Powershell. Now I have a script that is easy to pass around, can do this if I'm unavailable, and we can easily add/remove time zones/persons, and it just needed 5-ish lines of .NET inside of the Powershell script.


Or if you just want to parse date time in a script.


Not only .NET, any COM library or DLL as well.


Love how many people are telling you "don't use powershell" instead of actually helping. Some tips:

- Powershell isn't case sensitive. Typing `ConvertTo-Json` is annoying, but you can write `convertto-json` instead.

- `alias` tells you all the built-in aliases.

- The autocomplete is really, really good. Press ctrl-space to get all the options to tab complete commands, flags, or flag values. IE you can pipe something to `select -prop` and autocomplete all the fields of the thing. Also you can autocomplete with wildcards, like `*Json`.

- Flags don't need to be written out in full, you can write `select -exp` instead of `select -ExpandProperty`.

- Pipe stuff to `Out-Gridview` to get a filterable, sortable popup!


`Out-Gridview -PassThru` is pure gold!


I found nushell (https://www.nushell.sh) to be an impressive replacement "bash" for Windows

In terms of philosophy, think "Powershell but actually intuitive" : Every data is structured but command names are what you expect them to be. I usually don't even need to look at the documentation.

I liked it so much that I also replaced my shell on Linux with it, so I have the same terminal experience across all OSes


It's because Powershell is a bit anemic. Coming from bash to Powershell at first, I disliked PS because I couldn't use it like bash; handling text was a pain, the moment you try to get fun with PS like you might with bash Windows will absolutely slap you with permissions or restrictions, etc.

Powershell shines best when you're automating _Windows things_ or anything .NET adjacent. If you play inside the very specific rules Powershell allows, it works great and your Windows experience will likely be nicer.

So if you find yourself working on Windows and saying to yourself "wow, this works great but I wish I didn't have to babysit it like this", PS is your friend.

If you need to automate Active Directory, Exchange, MSSQL (I guess some general maintenance things or quick queries without SQL Management Studio), etc, PS is your friend.

Anything else, and you basically need to figure out how to get around the restrictions Microsoft put in to prevent you from doing this, usually using .NET code in your PS script.


There's a huge amount of powershell support for admins on MSSQL.

e.g. https://dbatools.io/commands/ https://github.com/microsoft/ReportingServicesTools https://learn.microsoft.com/en-us/rest/api/power-bi/

Also all the normal Active Directory and file system tools, but those are too broad to go into.


Are you using Windows’ built-in Powershell? If so, are you allowed to install the newer Powershell Core (based on .NET Core)? The latter has a lot of fixes and improvements compared to the built-in Powershell.


i dont think its called core anymore its just called powershell 7 now

and dotnet core, is just dotnet

i think they dropped the core part from the name as of dotnet 5


On unix you would have had to write that script anyways unledd maybe jq can help (?). I usually use convertto-csv and it works like a charm. Powershell is more like python than bash.

If you learn .net stuff it might make it more easy to use. You can access .net functions from powershell, so had you written that code in c# instead if node, you could reuse it in powershell anytime you want.

Although, personally I use shells to test stuff or for basic things, python kicks butt regardless of platform.

I hope your work let's you use wsl. If not, try running powershell.exe -version 1, that let's you bypass constrained language mode if that is the issue. Also, lookup set-executionpolicy and unblock-file, in case those are what you needed for the not allowed part. You can even bring your own powershell entirely! Powershell itself is an interface around System.Management.Automation windows/.net assembly. There are tools used in red-teaming where you just bring your own powershell interface and bypass any restriction. Even if you can't bring new exe's, no problem, you can relectively load assembly's and run them in memory, with or without powershell. Your org must be setup Crazy good if you have windows and there is no way to do whatever you want in powershell without admin rights. But don't get in trouble because of my advice!


> since I'm stuck on Windows at work

Are you allowed to install Cygwin? It does a lot for making Windows a civilized environment.


A really powerful feature in PowerShell is to download MSYS2 and then launch a proper shell :)

I started to learn PowerShell and probably will still have to proceed, but I so far successfully avoided it in my current job. MSYS2 for sometime was a relief (WSL was a bit crippled on my company's internal network)


Cygwin aside, WSL became pretty good actually.


WSL2 has some network shenanigans that make it fail when I'm on the corporate VPN. Cisco, MS and corporate IT say they are on it. They've been "on it" for the past 20-ish months.


https://github.com/sakai135/wsl-vpnkit fixes that problem for me, and is less annoying than other fixes I tried


If you're not allowed to install anything, asking for git automatically comes with git-bash, so it provides some cover for the real reason. And hey, bonus, you get git!


That’s how some colleagues dealt with the corporate network shenanigans that crippled WSL.


Related tangent: I'm forced to suffer Windows at work too, and have found that git-bash makes the CLI at least mostly tolerable. (It's still painfully slow and inefficient compared to zsh in iTerm on my personal M1 macbook, but it works.)


I love Windows, .NET, and Azure. Genuinely. But I use Bash. Powershell has a lot of what seems like custom-syntax for every little thing and I can't be bothered to memorize it.

Also, you guys can probably install GitBash and claim it just came with Git...


Actually you need to memorize million times less stuff to use powershell comparing to bash. This is because everything is a string in bash, so you have to learn a custom DSL for each task. Want to parse a JSON? Learn jq. Want to parse XML? Learn xmlstarlet. etc. In powershell you just use ConvertFrom-JSON to convert json to object and then use normal powershell syntax to access object properties instead of using custom DSL. That's the problem with bash - learn million DSLs for each file type, format, etc.


powershell's json handling leaves a lot to be desired. It's been awhile since I poked around but I never found a good parser and usually just switch to python for that and basically everything else to do with APIs (invoke-webrequest is really annoying to use also).

powershell is good for controlling the windows operating system and doing basic things with objects. sysadmins are more likely to have a decent time with it than developers. Although, you can use it to interpret dotnet which is kinda neat.


    $myJson = Get-Content .\test.json -Raw | ConvertFrom-Json 
    $myJson.Accounts.Users.asmith.department = "Senior Leadership" 
    $myJson | ConvertTo-Json -Depth 4 | Out-File .\test.json 
from: https://techcommunity.microsoft.com/t5/core-infrastructure-a...


And the depth maxes out at 100, for some reason. This is my problem with most PS data things, they work well on the surface but when you really get your hands dirty they run like dogs or have weird limitations.


You may need to format the output

Read powershell in a month https://www.amazon.com/Learn-Windows-PowerShell-Month-Lunche...

Microsoft had a good course for it, idk if this is good Youtobe has too https://learn.microsoft.com/en-us/training/modules/introduct...

I like powershell but I also dont use python or bash or whatever


>making powershell actually enjoyable to use

My solution was to stop using it and instead use dotnet-script

https://github.com/dotnet-script/dotnet-script

Scripting with the full power of modern C# has been a huge win for me. And same/similar scripts will work on Windows/Linux/Mac. As my work language is C#, I don't have to context switch to another language for scripting.


I may be missing something, but where is the PowerShell part? Mostly it is .c code and executables and only few .ps1 scripts.


This would be a great addition:

https://github.com/Gerenios/AADInternals




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: