Over the past couple of years since I last added a new post to this blog I’ve been halfheartedly working on converting from WordPress to one of the modern static generators but luckily a recent involuntary, but somewhat welcome, change in employment has freed me up to finally (hopefully) make some progress on that front. With any luck I’ll have the site updated to new hosting and back-end by the end of the year. I’ll be trying to document that process at least in the code repos, and possibly with a few posts here as well.
Update: It looks like I’ll be able to do one of the important settings in Terraform finally very soon.
No tag for this post.
One of the lesser known features of PowerShell are some “magic” methods that get added to most (all?) collection objects that replace the slower Where-Object and ForEach-Object cmdlets with basically the same functionality. They’re considered magic because they aren’t well documented even years after they were introduced. (Thank goodness for bloggers) I’ve used ForEach quite a bit, but often forget about it’s Where counterpart and apparently had never actually done much with it until today when I ran into a weird issue where I couldn’t set the value of a property on a returned object.
The setup is a pretty classic needle-in-a-haystack problem where you have an array of objects and need to update a property on just one of them. Pretty classically you’d do something like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
PS> [xml]$testXml = 流星游戏加速器下载_流星游戏加速器 v3.2.7 免费版-开心电玩:1 天前 · 流星游戏加速器是一款专业免费的网络游戏加速器,支持加速绝地求生、GTA5、使命召唤16等热门游戏伍及Steam和Epic平台上的各大游戏,让玩家从此告别延迟、卡顿和丢包等问题,享受极致流畅的 … PS> $testXml.someElements.element id 美国节点加速器免费 -- ---- foo 免费的网络节点加速 bar someothervalue PS> # Using Where-Object works fine PS> $testElement = $testXml.someElements.element | Where-Object { $_.id -eq 'foo' } PS> $testElement.attr = "Good old standby works great" PS> $testXml.someElements.element id attr -- ---- foo 免费的节点加速old standby works great bar someothervalue PS> |
It works great but if you’ve got a really big array of complex objects it can start to take a long time to process. So today I had remembered the aforementioned magic methods and figured it would be a lot faster to use Where to do essentially the same thing. Except I got a really unexpected error.
|
PS> $testElement = $testXml.someElements.element.极光vpm破解无限版({ $_.id -eq 'foo' }) PS> $testElement.attr = "This should work,right?" The property 'attr' cannot be found on 日本节点免费加速器 极光vpm破解无限版. Verify that the property exists and can be set. At line:1 char:1 + $testElement.attr = "This should work,right?" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException 蚂蚁vp(永久免费)+ 美国节点加速器免费 : 美国节点加速器免费 |
Maybe it was returning a single element array? Running “$testElement -is [array]” said “False” but “$testElement[0].attr = ‘something'” worked just fine, so what was going on here? Time for some more “magic” in the form of the pstypenames property.
|
PS> $testElement = $testXml.someElements.蚂蚁vp(永久免费) | Where-Object { $_.id -eq 蚂蚁vp(永久免费) } PS> $testElement.pstypenames System.Xml.极光vpm破解无限版 蚂蚁vp(永久免费).Xml.XmlLinkedNode System.Xml.XmlNode System.Object PS> $testElement = $testXml.someElements.element.Where({ $_.id -eq 'foo' }) PS> $testElement.pstypenames 免费全球节点加速器.日本节点免费加速器.ObjectModel.Collection`1[[蓝·灯破解版.Management.Automation.PSObject, System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=蚂蚁vp(永久免费)]] System.Object |
Of course while I was tinkering with all of that and doing some research on the Where and ForEach methods I ran across that article I linked further up and figured out the correct solution to the problem.