(This may also exist on Linux and Windows, but I can’t verify that) There’s currently (as of the date of this post) a bug with the .pkg installer for PowerShell 7.6.0 Preview 6: it doesn’t update the installed preview version, instead it overwrites the installed non-preview/stable version. Obviously, this is less than desirable, but it’s […]
Show full content
(This may also exist on Linux and Windows, but I can’t verify that)
There’s currently (as of the date of this post) a bug with the .pkg installer for PowerShell 7.6.0 Preview 6: it doesn’t update the installed preview version, instead it overwrites the installed non-preview/stable version.
Obviously, this is less than desirable, but it’s been reported to the team, so hopefully it will be fixed soon. But if you installed Preview 6, and you’re wondering why your system thinks you’re still on Preview 5, that’s probably why.
UncategorizedHow to return an arraylist from a powershell function without losing your mindPowerShellPowerShell Function ReturnsPowerShell N00b tips
While working on an update to Set-PowerShellSig, I noticed something weird. Well, not just weird, but bad. Say you explicitly create an arraylist or generic list in a function, we’ll call it myDumbReturn and you add things to it. Now, you want to return this arraylist or generic list so you say: You’d expect that […]
Show full content
While working on an update to Set-PowerShellSig, I noticed something weird. Well, not just weird, but bad. Say you explicitly create an arraylist or generic list in a function, we’ll call it myDumbReturn and you add things to it. Now, you want to return this arraylist or generic list so you say:
return $myArrayList
You’d expect that if you had a statement like $myReturn = myDumbReturn, that $myReturn would in fact be an arraylist or a generic list.
You’d expect that, but you’d be wrong. What you actually get is an array. So you go trolling the docs and in about_Return, you see this section, “Return values and the Pipeline” wherein you learn:
When you return a collection from your script block or function, PowerShell automatically unrolls the members and passes them one at a time through the pipeline. This is due to PowerShell’s one-at-a-time processing. For more information, see about_Pipelines.
So what’s happening is PowerShell is iterating through your arraylist or generic list, passing the contents one at a time to the calling code, and what you get is? An array.
In that section it talks about two options that will prevent this:
return ,$myArrayList
or
return Write-Output -NoEnumerate $myArrayList
Okay, it seems dumb this happens at all, but sure, I can do that.
Ope, nope, doesn’t work. So it turns out there’s another thing you have to do in conjunction with either of those options: in statements where you add things to the arraylist/generic list (and one would assume other operations, but maybe not), you have to either pipe the statement to Out-Null or preface the statement with [void], and mind you, you can do both, so:
function badArrayReturn {$theArrayList = [System.Collections.Generic.List[string]]::New()[void]$theArrayList.Add("item5")$theArrayList.Add("item6")|Out-Nullreturn ,$theArrayList}$returnedList = badArrayReturn$returnedList$returnedList.GetType()
and you get what you expect, $returnedList is in fact, a generic list:
It also works with the return write-object syntax. This is not in the Out-Null docs, nor could I find this info for write-object, and it’s not in the “About Return” docs either. I did figure it out after a lot of back and forth with a couple folks on BlueSky with far too much “you just don’t understand…”, “that’s how we’ve always done it”, and examples that didn’t apply. Finally one or both of them actually put the whole thing together so that’s cool.
I did report it as a bug to the PowerShell Github project, but the response was about the same: “that’s how we’ve always done it” and closed. Yes it’s misleading and kind of lying, but hey, it’s how we’ve always done it, so what can you do.
Evidently, changing bad behavior in software is literally impossible and simply cannot be done. Once written, software is a thing unto iron, and cannot ever be changed.
Sigh. Anyway, that’s how you avoid your arraylist and generic list returns from being silently coerced to arrays sans warning without a lot of PowerShell glitterati elitism.
I need a drink
(No one from the Apple world wants to get snarky or smug here. I’m in a mood, I have time, and Apple is far, far worse.)
A fairly significant update, 1.1’s Mac component leverages AppleScript’s Choose File so you can select multiple PowerShell files to sign at once. It took a bit longer than I thought it would because while you can create generic list objects in PowerShell functions, what gets returned is a generic array. Sigh. Anyway, it’s up at […]
Show full content
A fairly significant update, 1.1’s Mac component leverages AppleScript’s Choose File so you can select multiple PowerShell files to sign at once. It took a bit longer than I thought it would because while you can create generic list objects in PowerShell functions, what gets returned is a generic array. Sigh.
PowerShellautomationDownload Latest PowerShell Automaticallymac-powershellpowershell funPowershell Mac
One of the annoying things about well, any software is checking to see if you have the currrent version. This is a thing with PowerShell, and because the PowerShell team in its finite wisdom has decided to not just have a “latest stable/lts/preview” url, we have to figure this out manually. It’s not too bad […]
Show full content
One of the annoying things about well, any software is checking to see if you have the currrent version. This is a thing with PowerShell, and because the PowerShell team in its finite wisdom has decided to not just have a “latest stable/lts/preview” url, we have to figure this out manually.
It’s not too bad though, fortunately, the PowerShell team gives us a good way to check and a bit of simple comparison to help us determine if we have the newest version. The basic flow is “get the current installed version of PowerShell, then check to see if the current version on github is newer. If it is, download that.”
Now, there’s a couple caveats: the installed version is based on what you’re running the script in. So if you’re going between say stable and preview, if you run the version checker in stable, that will give the version for stable. You’ll have to run it in preview for that, and do your own version comparison. I’m just doing this based on stable.
To see what the current installed version of PowerShell is, we run $PSVersionTable.psversion.ToString() which gives us a nice neat value, so for stable on my machine, I get: 7.5.4
We then want to see what the current stable downloadable version is. Fortunately, the PowerShell team does us a solid by making that available from a stable URL as JSON data. For stable, the URL is: https://aka.ms/pwsh-buildinfo-stable. To check for lts or preview, change -stable to -lts or -preview. If we hit that URL, we get a json file with the following
The ReleaseTag is the thing of the most interest to us. When it comes to downloading, while not giving us a “latest” URL, the PowerShell team does give us a fairly consistent URL pattern. For example, for the installer package for the Apple Silicon macOS version, the URL is: https://github.com/PowerShell/PowerShell/releases/download/v7.5.4/powershell-7.5.4-osx-arm64.pkg, so we can see where we can use the ReleaseTag directly in the URL in between download/ and /powershell-, and then if we yank the leading v off the ReleaseTag, we can use that in the actual package name. Consistency is really handy. The script itself then is:
Get the installed version
Get the current github version
if the current github version is newer/greater than the installed version, download that package file to /tmp
We use Invoke-RestMethod as our “curl” command, since in this case, it gives us the JSON data in a usable way sans any custom parsing. From there, install it via whatever method you wish. Obviously, the script is a PowerShell script, duh. So the script:
#get the installed (stable) version
$installedPSVersion = $PSVersionTable.psversion.ToString()
#get the JSON data from github
$PSLatestStableVersionInfo = Invoke-RestMethod -Uri "https://aka.ms/pwsh-buildinfo-stable" -Method Get
#get the releasetag
$PSLatestStableReleaseTag= $PSLatestStableVersionInfo.ReleaseTag
#build the version sans the leading v
$PSLatestStableVersion = $PSLatestStableReleaseTag.Substring(1)
#test to see if github is newer
if ($PSLatestStableVersion -gt $testVersion) {
#github version is newer, build the download URL
$macOSPowerShellASPKGDownloadURL = "https://github.com/PowerShell/PowerShell/releases/download/$PSLatestStableReleaseTag/powershell-$PSLatestStableVersion-osx-arm64.pkg"
#build our download filename
$macOSPowerShellASPKG = "powershell-$PSLatestStableVersion-osx-arm64.pkg"
#now we download the file to /tmp
Invoke-RestMethod -Uri $macOSPowerShellASPKGDownloadURL -Method Get -OutFile "/tmp/$macOSPowerShellASPKG"
}
And that’s it. Run this, and when it’s finished, if the github version is newer, you’ll have that package file in /tmp (as $deity intended), ready to go for whatever your next steps are.
Uncategorizedmac-powershellPowerShellpowershell funPowershell Mac
Related to some projects I’ve been working on to get data out of the macOS ULS in a usable format for Splunk, I realized that it’s kind of a pain to figure out what to sift through via predicates. Like the subsystems are easy, they’re all in /System/Library/Preferences/Logging/Subsystems/. But the categories and senders and processes […]
Show full content
Related to some projects I’ve been working on to get data out of the macOS ULS in a usable format for Splunk, I realized that it’s kind of a pain to figure out what to sift through via predicates. Like the subsystems are easy, they’re all in /System/Library/Preferences/Logging/Subsystems/. But the categories and senders and processes can be a right pain in the keister. So, I built https://github.com/johncwelch/Get-ULSDump It creates a series of .tsv files, one per subsystem via the log command. I like TSVs, they’re easy to import into Excel and when sifting data, Excel is kind of good at it.
The file save path is hardcoded to ~/Desktop/securityLogs/ so you might want to look at that before running it. This was a thing I built for my needs, so eh.
The script itself is pretty straightforward. It builds a list of subsystems, then for each subsystem, it builds a log command: $predicateString = "/usr/bin/log show --style json --last 5m --predicate `'subsystem == `"" + $item + "`"`'" from there, it builds the full destination path and file name, runs the log command, converts that to a JSON object, and saves the subsystem, category, process, sender, event message, UID, and PID for each entry to a TSV file named after the subsystem.
Obviously one could easily convert this to dump out as json, whatever. Anyway, it solved a problem for me, so figured i’d share. It’s also a nice way to get lists of things to use with the log command. That’s kind of lacking on the interwebs.
Not a huge one, added iBridge data, so it now shows SIP/SSV/secure boot status, few other things. There’s not much to it if you’re running on Intel, most of this is AppleSilicon only. Available from the PowerShell Gallery at https://www.powershellgallery.com/packages/Get-MacInfo and the github site https://github.com/johncwelch/Get-MacInfo has been updated as well.
UncategorizedMac Warranty InfoPowerShellPowershell Mac
This was a feature someone asked for with Get-MacInfo, and now that I have it, I can work on integrating it. Here’s the basics, the script is on the github site, and VERY REAL WARNINGS: So this is not as reliable as i’d like it, because of the warnings above, but for now, this is […]
Show full content
This was a feature someone asked for with Get-MacInfo, and now that I have it, I can work on integrating it. Here’s the basics, the script is on the github site, and VERY REAL WARNINGS:
This is incredibly fragile, as it relies on a directory, com.apple.NewDeviceOutreach, being in ~/Library/Application Support/ for the user running the script. I’m not even going to try to play “peekaboo in other user homedirs” with a generic script, much less with a PowerShell module. Yes there are ways to do that. No I am not doing any of them.
There can be multiple plist files in that directory covering many items. For example, in mine, I have one for my current M4 MacBook Pro, one for my Intel MacBook Pro, and two each for my airpods. There’s no good way to tell which one is for the device this is running on, like none. So, this script matches the hardware type (hardcoded in this example, but you’ll get the idea) and reports for everything that matches. If anyone can come up with a way to match “what this script is running on” to “this is the correct file to pull data from, by all means, let me know!
Playing games with Set-Variable and Get-Variable is less than ideal, but it is what it is
So this is not as reliable as i’d like it, because of the warnings above, but for now, this is the only way to really get this info. Should Apple fix this, AND THEY SHOULD, it’s well, better than nothing. The script is heavily commented, so you should be able to grok what’s going on with it.
rearchitected the system_profiler sections to use the JSON output to get info via directly addressing the items rather than hoping for the best with “this is that line of the array in the output. WAY less fragile.
Redid the hash table building to eliminate an assload of duplicate entries. We now account for Apple Silicon/Intel differences as we need them rather than duplicating the entire thing.
Added Power info for battery, AC power, and UPS.
Removed POST test items, they seem to have been removed in a recent OS update
Both modules are finally published so they can be installed the “right” way! Get-ChooseFile Get-ChooseFolder Get-Help is your friend and there’s documentation on their respective Github repo pages, available via the “Project Site” links for the respective projects
Show full content
Both modules are finally published so they can be installed the “right” way!
Get-Help is your friend and there’s documentation on their respective Github repo pages, available via the “Project Site” links for the respective projects