During my talk at JNUC, a few folks pointed out that my Get-Macinfo script didn’t work well on Apple Silicon. I wasn’t surprised, but as I don’t have an Apple Silicon Mac, I can’t exactly test for that. However, some of y’all really came through with details on command results, and with the help of folks, in particular Kelly Dickson and Dr. Michael Richmond, I was able to get the info I needed.
For Apple Silicon, in the system profiler hardware report, the following values:
don’t exist. Not a shock, but as that query is dumped into an array, missing 5 items meant my array references were all wrong.
I’ve got the first update for Apple Silicon up at ye olde github site, so anyone with an Apple Silicon Mac who wants to look at it and feels like installing/running PowerShell on their Mac (if they don’t already have it) can beat on it. It still seems to work correctly on Intel.
Again, thanks to everyone who helped out, it’s really appreciated, and if anyone has anything they’d like to see added to the list of things Get-Macinfo reports on, I’m happy to add where I can.
So obviously, I have a fondness for PowerShell on macOS, but one of the downsides with really integrating it into things is being able to rely on it as a resource. It’d be nice if you could just include it with a script or bundle, so that it was available for that script or application to use as needed.
Well, turns out, you can, thanks to the PowerShell team making some really good decisions in how they distribute PowerShell on macOS. If you download the installer bundle from the PowerShell github site, https://github.com/PowerShell/PowerShell/releases/tag/v7.2.1 (the current stable version as of this post), and you open the bundle up in something like Pacifist, you realize that all the important powershell bits outside of the man page and an app launcher are all in the same directory:
When I saw that, I decided to do a really quick and dirty test of my “Portable PowerShell” thought. So using Script Debugger, I created a script bundle, which is an AppleScript, but in a bundle format, which means it has the Contents/Resources/ tree. I then copied the usr/local/bin/microsoft/powershell/<version> bundle from the install package into the resources folder. In the script bundle itself, I set up the path to that bundle:
set thePwshAlias to ((path tome as text) & "Contents:Resources:powershell:usr:local:microsoft:powershell:7-preview:pwsh") asalias set thePwshPath to quoted form of (POSIX path of thePwshAlias)
Then the statement that does the test of this:
do shell script thePwshPath & " -c \"Get-PSDrive\""
And the expected result:
Name Used (GB) Free (GB) Provider Root
---- --------- --------- -------- ----
/ 782.49 149.06 FileSystem /
Temp 782.49 149.06 FileSystem /var/folders/0_/h5qr4rfj2
Which was the expected result. Now, some caveats:
This is literally the extent of my testing. Making this work with custom modules, etc, is going to involve more work on the setup, if that’s even possible.
I HAVE NO IDEA IF THE POWERSHELL LICENSE ALLOWS THIS. If the lawyers get flustered and stern, telling them “Well John said you could do it” will result in me laughing and saying “Yes, technically this is possible, I made no claims as to legality. It may be fine, it may be verboten, I have not checked either way.
My thought on this is that if you were creating a cross platform app and you wanted to implement PowerShell for that app, this is a way to ensure it works on macOS without making the user do a bunch of separate installs. It’s a proof of concept that happens to work, so coolness. As I get time, I’ll beat on it more, there’s some real potential here.
Also, many thanks to the PowerShell team for doing things in a way that made this trivial to test and play with.
This will probably work within ASOC too, since do shell script works there. On macOS, the powershell “executable” is pwsh, usually in usr/local/bin/pwsh for the non-beta versions. If you run pwsh -h, you see that the pwsh utility is quite versatile, and by using the -c parameter, you can treat it like osascript, in that you can pass it a single command as a string, or an entire script block. You can also pass it a PowerShell script with the -f command. So to use this from within AppleScript/JXA, (AppleScript syntax shown), it looks like:
do shell script "/usr/local/bin/pwsh -c \"Get-PSDrive\" "
You can also use this with custom modules:
do shell script "/usr/local/bin/pwsh -c \"Get-MacInfo HardwareModelID\" "
So if you want to use a slightly more coherent shell environment like PowerShell from within AppleScript, you can.
Okay, this is really just so it maybe gets picked up by Google. If you have a custom/homegrown PowerShell Module you want to install in macOS, and have them “live” there as it were, you want to copy the module folder with at least the .psd1 and .psm1 files in it to: ~/.local/share/powershell/Modules. Make sure the module folder has the same name as the module. So in the case of my Get-MacInfo module, (yes, I know, the EFIVersion is a bit weird at the moment), you would create a folder named “Get-MacInfo” in ~/.local/share/powershell/Modules, and copy the Get-MacInfo.psd1 and Get-MacInfo.psm1 files into it, then restart any running powershell sessions. At that point, Get-MacInfo would just work:
% pwsh -c "Get-MacInfo HardwareModelID" HostName: not set Name Value ---- ----- HardwareModelID MacBookPro16,1