I was under the impression that module manifests allow only DATA stuff. In fact, if you try to use cmdlets or variables in them, you get the usual Data-language errors, like this:
Import-Module : The module manifest ‘C:\Modules\Test\Test.psd1’ could not be processed because it is not a valid PowerShell restricted language file. Please remove the elements that are not permitted by the restricted language: The command ‘Get-ChildItem’ is not in allowed in restricted language mode or a Data section.
Import-Module : The module manifest ‘C:\Modules\Test\Test.psd1’ could not be processed because it is not a valid PowerShell restricted language file. Please remove the elements that are not permitted by the restricted language: A variable that cannot be referenced in restricted language mode or a Data section is being referenced. Variables that can be referenced include the following: $PSCulture, $PSUICulture, $true, $false, and $null.
BUT THEN I came across this in the Windows 7 built-in BitsTransfer module:
RequiredAssemblies=Join-Path $psScriptRoot “Microsoft.BackgroundIntelligentTransfer.Management.Interop.dll”
AND IT WORKS?!
Well, that’s very weird, because Join-Path is certainly not allowed in a normal “restricted language” file, and (as you can tell from above) neither is $PsScriptRoot — in fact, as far as I know, you shouldn’t have to do that at all, since RequiredAssemblies knows enough to look in your module folder… but nevermind that, why does it work?
So I went digging, and it turns out that although they are parsed as Restricted Language (like a “data section,” see about_Data_Sections), module manifests are allowed extra cmdlets: “Import-LocalizedData”, “ConvertFrom-StringData”, “Write-Host”, “Out-Host”, “Join-Path” and even special variables that aren’t normally allowed in data sections: specifically $PsScriptRoot which is the ModuleBase (the parent folder of the psd1) and environment variables ($Env:), plus the usual $PSCulture, $PSUICulture, and of course $true, $false, and $null.
However, although you can use those variables, you can’t embed them in strings, so if you wanted to use $Env:Windir or $Env:Temp as part of a path (for instance), you need to take advantage of the availability of Join-Path.
Now, I can’t find this documented anywhere (although I did add it to the module manifest documentation on MSDN), but it’s true, nonetheless — you’ll just have to trust me
Yeah, PowerShell is starting to drive me crazy again.
Microsoft has been very busy this year … and in these last couple of months before the general availability of Windows 7, they’re trying very hard to crank out the tools necessary to encourage development of Windows 7 applications.
The first tool out of the gate, of course, was the Windows API Code Pack for the .Net framework. A nice library that makes it simple to write applications that take advantage of new Windows Vista and Windows 7 features like Libraries, Task panes and jump lists. Of course, that library has a major problem: it’s got an ugly and confusing license. Rather than using one of the standard Microsoft Open Source Licenses, the team used a license from the dark ages that features the vague “Excluded Licenses” clause and other ugly terminology.
More recently, Microsoft has announced a Platform Update for Vista which is intended to allow Vista to run most applications designed for Windows 7. The Platform Update is a set of runtime libraries which includes the Windows Ribbon control; Automation Manager Library; DirectX updates for hardware acceleration; DirectCompute for hardware-accelerated parallel computing support; the XPS printing library; the Windows Automation API; and the Windows Portable Devices Platform, which standardizes data transfers across apps and portable devices. This important package will be made available through Windows Update (and applications will be able to prompt you to download it) and it is in public beta with more information on the Windows Team blog. A couple of pieces of that will be made available for Windows XP; particularly the Automation API, which allows accessibility tools and test automation tools to access Windows user interface in a consistent way — this will mean that the next release of WASP will work flawlessly across Windows XP, Vista, and Windows 7.
Also in the works is the Remote Desktop Connection 7.0 (RDC7) client for Windows XP and Windows Vista to allow these older clients to take advantage of all new server features in Windows 7 and Windows Server 2008, including multi-monitor support and media redirection. There’s more information about that on the Remote Desktop team blog.
And finally, the release candidate for the Windows Management Framework (WMF) is also available. The WMF will include WinRM (Microsoft’s implementation of the WS-Management spec), PowerShell 2.0, and BITS for Server 2008, Windows Vista, Server 2003, and of course, Windows XP. This means that if you’re on Vista, or still using Windows XP, you can now upgrade from the PowerShell 2.0 CTP 3 to this release candidate and expect remoting to work!
All of these should be seeing final releases in the very near future, and some of them possibly by the time Windows 7 is released to the public.
I gave a presentation at the upstate New York PowerShell user group last night about the new stuff in PowerShell 2 — giving it really made me think about how I’m just so used to PowerShell 2 that I’ve forgotten about how much of it is new in this version — and how cool each of these new things are. In fact, in my list of 7 areas that I talked about, I bet we could find a PowerShell MVP for at least each of the top 6 that would be willing to argue for that one being the most important new feature in PowerShell 2
Having said that, below is the text from my slides … my personal “highlights” of what’s new in PowerShell 2.
Organization
Private variables and functions
<#
.SYNOPSIS
A short description of the function.
.DESCRIPTION
A longer description of the function.
.PARAMETER <parametername>
The documentation for that specific parameter
.EXAMPLE
C:\PS> some example code
.LINK
Get-AnotherFunction
.LINK
http://yourwebsite.com/help/documentation
#>
New-PsSession
Get-PsSession
Remove-PsSession
Export-PsSession
Import-PsSession
Enter-PsSession
Exit-PsSession
Invoke-Command
Finally provides support for asynchronous Events, for GUIs, timers, WMI, and remoting
There are so many fun things you can do in Windows when your scripting language allows you to make PInvoke calls to Win32 APIs … but I have to say it’s amazing how many things have been added to Windows recently and still left out of the .Net framework …
Anyway, on to the Aero Peek stuff. If you haven’t seen it, Aero Peek is a feature of Windows 7, which lets you get a peek at your desktop, or at a single window for a moment. Basically, you can press Win+Space (the Windows logo key and the space bar) and all of your open windows instantly turn transparent, revealing … whatever was on your desktop: wallpaper, icons, and gadgets. You can also use it by hovering your mouse on the right corner of the taskbar, or you can peek at a single window by hovering over it’s taskbar button and then over it’s thumbnail.
In any case, I have a couple of windows which I would like to have stay visible on the desktop when I hit the aero peek hotkey: Rainlendar and Miranda. It turns out there’s a simple API call for this: DwmSetWindowAttribute which lets you set the DWMWA_EXCLUDED_FROM_PEEK attribute to ENABLED … causing a window to no longer hide when you press that hotkey. Of course, that API call should be made by those apps, in response to a user setting (so I’ve told their authors about it), but it doesn’t have to be (so I wrote a script to do it myself).
In the old days, I would have written a little systray app which would give you a popup list of all windows, or perhaps added a menu item to a window’s right-click menu … and I would have had to deal with creating some way to persist which apps you wanted to apply this to, and then I could have applied the setting to them whenever you opened them.
But now, I have PowerShell. I don’t need to give you menus and store settings, because I can just let you edit a little script instead.
So here’s a script which will let you turn off Aero Peek transparency for windows by window title and/or process name … Once you have this function available, you can keep Rainlendar’s calendar, tasks, and event windows all visible by just running Remove-AeroPeek -Process Rainlendar2 or you can keep your Miranda contact list visible by running Remove-AeroPeek "Miranda IM" (although you should not that depends on the window title matching just that one window — and Miranda lets you change what your title is, so you may have to adjust it).
Of course, that script really deserves explanation, because it’s showing off quite a few advanced things…
The first thing is that I’m using a Try/Catch block in the BEGIN block to make sure I only execute that code once. You can’t call Add-Type with the same code multiple times in a single PowerShell session, because the type will already exist when you call it the second time. So the code in the try block will throw an exception if the type doesn’t already exist, and in the catch handler, we’ll create the type, and define the other function we need.
Add-Type is a super-powerful cmdlet which compiles code on the fly (or imports types from pre-compiled assemblies). In this case we’re using it to import a little class called Dwm which I started writing myself from PInvoke.net and the MSDN documentation, but then eventually copied most of from a NeoWin forum thread… All this class really does is define the API function and the flags we need to pass to it, and then provides a wrapper for the DwmSetWindowAttribute call. We could have written that call in PowerShell, but at the end of the day, once you start compiling C# code in PowerShell, it’s hard to know when to stop
The Select-Window function is (yet another customized version of) a function I wrote awhile back on PoshCode as part of my (still in progress) rewrite of WASP to use the UIAutomationClient … I’ve just modified it to add only the three properties of the window that I’m interested in: Title and ProcessId (for identifying the correct windows) and Handle (for passing to the DwmSetWindowAttribute call). It uses the RootElement property of System.Windows.Automation.AutomationElement to do a search, and then a series of GetCurrentPropertyValue calls to determine the Name, ProcessId, and NativeWindowHandle of the windows it finds.
That’s pretty much all there is to it, other than filtering out the window(s) that we want and actually calling the API. I think I’m going to have to play a little bit more with this to see what else we can do — I’ve already realized that this means we can make little widgets with PowerBoots and set them to stick around just like regular desktop gadgets …
So, last year around April, I wrote this module I called “HuddledTricks” ... it has a function for hiding windows, and another for showing them, along with a function called Wiggle-Mouse which, well, wiggles your mouse cursor (and one called Steady-Mouse to stop it).
So anyway, today I was playing with something else and with my WASP module, and discovered that you can hide the Windows 7 taskbar without hiding the start menu or button.

This seemed cool enough to motivate me to finally actually publish my HuddledTricks module, so have fun, and don’t prank too many people.
So, I wrote up this great explanation about how much the Shell in Windows 7 has changed from Vista, and how this shows that this Windows 7 beta is a much bigger deal than most of the whiners in the press are giving it credit for being, and explain about how I used to be a shell developer, and how that means I should have credibility when it comes to discussing changes in the taskbar, systray, desktop, and their various preference panels ….
I think the drivers for Mesh, (maybe VirtualCloneDrive, or Eset’s NOD32) ... didn’t like going into hibernation. Anyway, I lost all that, so let me just list for you some of the changes just in the shell. I’m going to ignore the multi-touch capability, and “Homegroup“s, and the “Libraries” that are really impressive if you’ve never learned how to make a junction …
OK, there’s actually more changes than just those … the desktop wallpaper has a built-in “slideshow” feature, so you can have your wallpaper change every day (or every 10 seconds, or something in between). The UAC prompts have a link on them to the UAC preference panel where you can disable UAC as easy as sliding a slider. The taskbar can “learn” just like the start menu does, to keep the apps you use the most always available… or you can just pin those apps to the taskbar manually (again, just like the start menu).
So there’s lots of cool new features in the shell, even without getting into touch interfaces and other stuff, and generally, I think this represents a bigger change than the windows 95-98 and possibly even bigger than 2000 to XP, and on top of all that, the relative performance of the system seems to go in the right direction for a change.