2.0 - Stuff to deprecate

Topics: Developer Forum
Oct 4, 2009 at 1:49 AM
Edited Oct 4, 2009 at 2:24 AM

ConvertFrom-WmiTimeSpan.ps1ConvertFrom-WmiDateTime.ps1 - DmtfDateTimeTypeConverter allows simple [DateTime]$str or [TimeSpan]$str casts

ConvertTo-DmtfTimeInterval.ps1ConvertTo-DmtfDateTime.ps1 - i'd rather create a [DmtfDateTime] & [DmtfTimeInterval] classes to allow symmetric casting (DMTF) [String]->[DateTime]->[DmtfDateTime]( -> [String])

Start-Process - PS2 Start-Process seems to be on par with our implementation, save for remote capability. I don't see this as an issue, given that PS2 has built-in remoting that is much better than WMI.

Stop-RemoteProcess - see above, there's a real remoting now 

VirtualServer.ps1, Connect-VirtualServer.ps1 - does anyone use it these days? let's hope not

Select-Xml - PS2 version seems OK?

[nevermind, bad idea] Convert-Xml - i'd rename it to Invoke-Xslt, as to avoid confusion with PS2 ConvertTo-Xml, which seems to be a less stupid version of Export-Clixml

Select-Random.ps1 - replaced by PS2 Get-Random 

Get-Random - the PS2 version does not support floats and  byte arrays. any ideas how to provide this functionality? New-RandomBuffer? Get-RandomDouble? These are stupid names :(

Remove-Accessors.ps1 - Get-Member doesn't return them anymore

ScriptBlockDelegateTypeConverter - not needed

Get-PscxCmdlet|Script|...* - replaced by Get-Command -CommandType XXX -Module Pscx 

ConvertTo-*LineEnding - change to single Convert-LineEnding command 

Get-WebService - replaced by PS2 New-WebServiceProxy

Resize-Bitmap - rename to Convert-Bitmap

any thoughts, guys? feel free to add more

Oct 4, 2009 at 2:06 AM

I with you on the DMTF date/time functions although we need to start a release notes file so we can document the deprecated stuff.  BTW is the plan to put the deprecated stuff into a "deprecated" module?  If so, then I guess we could just gen the deprecated release notes from a Get-Module on this module.

I wonder if  should let folks know when they're using a deprecated command - perhaps with a warning message? 

Ditto on the virtual server stuff - that is too vertical IMO and shouldn't have ever been added. 

WRT to Convert-Xml, I want to leave this one alone.  I find Convert-Xml more descriptive than Invoke-Xslt which describes how it works and not what it is doing i.e. converting XML to some other representation.  Besides, we have quite a few production scripts using this one.  I *personally* have to be careful on some breaking changes.  :-)

I'm OK with the rest going into the deprecated module (or just plain removing like Get-Pscx* and Remove-Accessors).

Oct 4, 2009 at 2:14 AM

BTW what do you think about converting all the various ConvertTo-*LineEnding cmdlets into a single Convert-LineEnding -ToWindows|-ToUnix|-ToMacOs9.  It's a subtle change but I think we should strive to keep the surface area (number of commands) low.  We could create some legacy functions to route to the new cmdlet with the appropriate switch.

Oct 4, 2009 at 2:19 AM

We should also move Get-WebService into deprecated because Posh 2.0 has New-WebServiceProxy.

Oct 4, 2009 at 2:19 AM

Yeah, definitely a separate module. I would even vote for a separate assembly. Warning message is a good idea, too.

The deprecation module should export aliases for whatever we are going to rename. (eg. Select-Random).

WRT ConvertTo-LineEnding, I say yes. Again, old names can go into the Pscx.Legacy.psm1

Oct 4, 2009 at 2:23 AM

Updated the list. What shall we do about the Get-Random command?

Oct 4, 2009 at 2:24 AM

Yeah I've been planning on separating the legacy cmdlets into a legacy assembly all along.  How is it going on your branch?  I'm beginning to wonder if we shouldn't just go ahead with this modular approach.  While I would like to get something out soon (helps my renomination prospects :-)) going from 1.1.1 to 1.2 was quite a bit of a change.  We are going to do this to folks again with this switch to module-based.  I guess I would rather suffer the pain once instead of over multiple release.  So, do you feel good about RI'ing your branch back up to trunk?

Oct 4, 2009 at 2:26 AM

Get-Random, Select-Xml and Start-Process should all be moved into a separate assembly.  What should be call this?  Pscx.Deprecated.dll or Pscx.Legacy.dll or Pscx.???.dll?  I lean a bit towards deprecated because if a cmdlet exists in PowerShell, I think folks should try to use it first before the PSCX version.  You can count on that cmdlet being available on all PowerShell 2.0 installs.

Oct 4, 2009 at 2:43 AM

Well there's still a lot of work to do; Database,  IO.*, Reflection, Security, and the root commands aren't modularized yet. Also the two providers must be changed to not create default drives.

Moreover, we should get rid of the Profile directory:

moving cd..., dirx, Invoke-Ternary and Invoke-NullCoalescing, qs, ql and perhaps others from Generic*.ps1 functions into some Pscx.Convenience.psm1 (?) module
or perhaps a Pscx.Navigation.psm1 (?)  with cd+ cd- et al. and Convenience with the rest... (BTW I'd much rather see the cd+- stuff implemented as a cmdlet, but that can wait for next release)

Get-ExceptionForHR/Win32 + Resolve-Error into Pscx.ErrorHandling.psm1 (? bad name)  

Edit-*Profile and Update-Profile into Pscx.ProfileManagement.psm1

transcript stuff should also get a module

Set-ReadOnly Set-Writable should be (ideally) reimplemented as an advanced functions inside of the IO module

RegexLib.ps1 should probably be part of the Text module 

+ get rid of the PscxConfig.ps1 auto-dot-sourcing thing.

So tell me if you want me to do it in trunk or not...

Oct 4, 2009 at 2:43 AM

Pscx.Deprecated.dll sounds good

Oct 4, 2009 at 3:24 AM

OK I've created Pscx.Deprecated and did some renaming on project dirs so they match the assembly names they output.  Should both Pscx and Pscx.Deprecated have Module dirs or should we have a solution level Modules folder (don't think it needs to be a C# project file)? 

As for this:

+ get rid of the PscxConfig.ps1 auto-dot-sourcing thing.

As long we still have a good story for pulling in some of the "optional" functions like the eye candy stuff - which we don't autoload by default anymore.


Oct 4, 2009 at 3:50 AM

I think that Convert-LineEnding is the right verb-noun … I’d suggest adding “crlf” (and “rn” maybe?) as aliases for “windows” (with similar aliases for the others)…

Question though: does switching from many cmdlets to many functions and one cmdlet really change the surface area?  How many people are filtering out functions when they Get-Command?

From: r_keith_hill

BTW what do you think about converting all the various ConvertTo-*LineEnding cmdlets into a single Convert-LineEnding -ToWindows|-ToUnix|-ToMacOs9. It's a subtle change but I think we should strive to keep the surface area (number of commands) low. We could create some legacy functions to route to the new cmdlet with the appropriate switch.

Oct 4, 2009 at 4:24 AM

The "many" functions is just to maintain compatibility for at least one rev.  I think I would have the functions do a Write-Warning "This command has be deprecated and replace by Convert-LineEnding -ToWindows.  Please update your code to use the new command."  Over time (a couple of revs), we will get rid of these "deprecation stubs".

Oct 4, 2009 at 11:41 AM

EyeCandy will be a module too. Our default profile should look like this:

ipmo Pscx
# ipmo Pscx.Deprecated
# ipmo Pscx.EyeCandy
Oct 4, 2009 at 11:51 AM

perhaps we should organize the resulting project like this

\ (on $Env:PSModulePath)
        Pscx.Core.dll, Pscx.dll, ...
    \Programs (on $Env:Path)
        less.exe, EchoArgs.exe, ...
        format.ps1xml, type.ps1xm

The deperecated package would just add a module and an assembly into the respective directories. Or it could be extracted into a separate root directory and added to the PSModulePath on its own; both ways should work.

I'd rather have the module files as part of the c# project for our convenience.

So, Keith, should I RI the Modular branch?

Oct 4, 2009 at 5:53 PM

deprecate New-HashObject: New-Object PSObject -Property @{ X=124; Y='abc'; Z=42.01 }

remove Pscx\New-Object ScriptBlock to delegate functionality - delegate casting works out of the box

Oct 4, 2009 at 7:22 PM

I agree where there are module components coming from that assembly. However if we wind up with some script only modules I wonder where they should go e.g. Pscx.Cd.ps[dm]1 (at least until I rewrite this as a cmdlet which is on my todo list).  I guess we could keep it under the Pscx C# project for convenience.  I would like the output dir for that project to reflect the "installed" state of PSCX makes the whole edit-compile-debug cycle easier.

As for the dir structure, I don't see a burning need to rename Apps -> Programs but if you feel strongly about it - go for it.  As for assemblies, since there will only three (plus supporting ps1xml help files) I don't see a good reason to bury them.  They're what the PSCX module is all about.

Go ahead RI the modular branch just watch out for projects I renamed - eek - hopefully that won't cause you too many headaches.  :-(   Sorry I have been wanting to do some house cleaning for a while.  I prefer that project names match the associated assembly name and namespace.

Oct 4, 2009 at 7:24 PM

BTW the PSCX project references should be coming from one of the Pscx/Trunk/Imports dirs.  I had to patch up some references that got broken in the Pscx snapin project.

Oct 4, 2009 at 7:32 PM
Edited Oct 4, 2009 at 7:35 PM

Jachym, regarding this:

[Trunk] removed ConvertFrom-Wmi*

I want to move these into the deprecated module and define like so:


begin {
    Write-Warning "ConvertFrom-WmiDateTime has been deprecated.  In its place you can " + `
"use a [DateTime] cast to convert a DMTF date string to a .NET DateTime " + `
"object. While this function remains in this version of Pscx it will " + `
"be removed a future version. ") } process { if ($_ -ne $null) { [System.Management.ManagementDateTimeConverter]::ToDateTime($_) } } end { if ($wmiDateTime -ne $null) { [System.Management.ManagementDateTimeConverter]::ToDateTime($wmiDateTime) } }

So let's be careful about which commands we remove (I agree that there are some we could just nuke like the contents of Debug.ps1).  For the bulk, I would like to stage their removal.

Oct 4, 2009 at 7:51 PM

OK I'm putting these ConvertFrom-Wmi* functions back in the Pscx.Deprecated\Scripts folder.

Oct 5, 2009 at 12:17 AM
Edited Oct 5, 2009 at 12:27 AM

OK I'm trying out the data section to only specify the deprection message once for multiple functions.  This is what it looks like:

function ConvertFrom-WmiDateTime {
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]

    begin {
        Import-LocalizedData -BindingVariable msgs -FileName Messages
        $warning = $msgs.DeprecatedFunctionWarningF2 -f $MyInvocation.MyCommand.Name,`
                    'In its place you can use a [DateTime] cast to convert a DMTF date string to a .NET DateTime object.'


    process {

Anyway, kind of fun to play with these message catalogs.

Oct 5, 2009 at 12:26 AM

Yeah, just wanted to talk about them. I agree that we should do something about the user-visible strings scattered through the code; however this one string should probably be somewhere compiled cmdlets can reach. And if we devise such place, I'd like to put everything in there, so we don't have to manage both a psd1 and a resx...

Oct 5, 2009 at 12:32 AM

At first I was going to use generic command but I thought from a user point of view that I wanted to see "this function will be removed".  So I think it would just fine to have one RESX string in the assembly for compiled cmdlets and a couple of shared strings in a data section (one for functions, one for scripts and maybe one for aliases).  I believe in DRY up to the point where things become too convoluted.  BTW I was thinking about going the RESX route at first but the auto-gen'd properties type is internal.  We could front that with a public type but then again this seemed like a reasonable place to use data sections.

Oct 5, 2009 at 12:36 AM
Edited Oct 5, 2009 at 12:40 AM
The RESX generated class can be made public, there's an "Access Modifier" combobox in the editor.
Oct 5, 2009 at 12:42 AM

Cool.  Didn't know about that trick - learned something new today.  Thanks!  We could put the script string in a resx but using the data sections make it extremely trivial to localize - not that we've ever really worried about doing that.   You just copy the Messages.psd1 file to a dir like de-DE and party on the strings in the catalog - nothing more.  Pretty nice.

Oct 5, 2009 at 7:17 AM

Jachym, I'm done for the night but I've got a couple of thoughts/issues.

1.  I don't think it is necessary to name module files with "+Aliases".psm1.  I have been removing the "+Aliases".  In some cases 
moving the aliases from the module to the deprecated module leaving no aliases in the module.  I don't think we need this
level of detail in the naming of the module.

2. Jaykul is right.  Where we have a manifest file, we should be importing that and that should reference the PSM1 file. 
I have started to update the modules to fix this.  See Pscx.Math.psd1, Pscx.Net.psd1, Pscx.Xml.psd1 and Pscx.psd1.

3.  I created a Pscx.FileSystem.ps[dm]1 files and moved the appropriate formats & types over into the Modules\FileSystem

4.  I moved the top-level manifest file (Pscx.psd1) up to the top level right under the Pscx dir.  I think it should be side-by-side
with Pscx.dll and friends plus it needs to be this way for import-module to find it under the users's Modules\Pscx dir.

5. I'm beginning to have second thoughts about the number of nested modules.  This adds to the testing complexity and makes
PSCX overall more brittle.  This is a problem we have been fighting with the source code base (in that case, it is due to the
complexity of the code).  I'm reminded of something I read from Microsoft's Krzysztof Cwalina - something to the effect of:
"Every new feature/idea starts out at -100 points and has to be proven to move that point total significantly past 0 before it is worth
adding to the code base".  That is, I love everything we do that simplifies the code base, I'm very suspicious of things we do that
makes it harder to deal with (build, debug, test, deploy).  Ultimately it has been Oisin and I doing the bulk of the testing &
deploying work.  I'm not sure I want to sign up to support so many modules over the long haul.  As an example, does SIUnits
really need to be its own module (its got one cmdlet)??  Anyway, food for thought.  I do like this direction just to be clear. 
I'm just thinking we might want to avoid going overboard on splitting this thing up.

Oct 5, 2009 at 8:00 AM

BTW if you want to build & try this stuff out, replace the current PSCX goo in your profile with this:

Import-Module ~\Pscx\Trunk\Src\Pscx\bin\debug\Pscx.psd1
Import-Module ~\Pscx\Trunk\Src\Pscx.Deprecated\bin\debug\Pscx.Deprecated.psd1

There's still lots of stuff broken but better to start dog-fooding it now.

Oct 5, 2009 at 8:39 AM

1) if we can get rid of the aliases, great

2) ditto, if there are no potentially conflicting aliases, there's no need for separately-importable script modules.

4) I don't think this is a good idea. It will cause confusion as to whether Pscx.dll or Pscx.psd1 is loaded, and you need to add two paths to PSModulePath. I'm for assemblies in root and modules separate.

5) No, SIUnits don't need to have a separate module; I created it mostly for testing the idea, and I'm fine with it becoming part of a larger module. OTOH, I'd rather see a few more smaller modules, than one large monolithic "Utils" module, grouping together unrelated things.

Oct 5, 2009 at 10:30 AM
Edited Oct 5, 2009 at 10:32 AM

just few more ideas regarding 4)

  • we need to have Pscx.psd1 in the root to support xcopy deployment into $PSHome and Documents
  • but we should also support deployment into eg. source control enlistments, with support for importing submodules, therefore the Pscx.*.psd1s should be in the same directory as the main Pscx.psd1 (the root). 
  • having Pscx.psd1 and Pscx.dll and other assemblies in the root directory is the only way of satisfying the above requirements in the VS Output directory

therefore, everything should be in the root. thoughts?

and regarding the Deprecated module and globalization:

  • I think the Import-LocalizedData command should be called during module load, not every time a function is called. All module variables are private unless explicitly exported.
  • I would prefer the hashtable literal syntax, instead of ConvertFrom-StringData
  • also, is it possible to pull the <##> help into a separate file? If not, the localizability of strings is almost useless.
Oct 5, 2009 at 3:10 PM

Regarding 4.

I'm running it now as-is and the nested modules works.  I think we can leave Pscx.psd1 in the root dir (and output dir) and organize the nested module defs under a Modules folder.

Regarding globalization.  I'm just doing what the Windows 7 Troubleshooting Packs do (take a look at $env:\windir\Diagnostic\System\Aero).  As for localization for function help, yes but you then have to convert the help syntax to MAML.  Yuck!!!!

Oct 7, 2009 at 5:11 PM

I just checked in a modified pscx.psd1 and a new pscx.psm1. Let me know what you think:

The pscx.psd1 no longer statically imports nested modules; instead it loads pscx.psm1. By default this module will import all nested modules in modules\, while also suppressing the "warning non-standard verbs" messages. This prevents us getting duplicate warnings from the nested imports. Instead we only get a single warning from the root import when it reexports to the caller's namespace.

Also, the root ipmo can now accept an -argumentlist (shortcut is -args) which allows the caller to import a subset of the nested modules:

# running from bin\debug hence .\pscx.psd1
ps> ipmo .\pscx.psd1 -args math,text,net

PowerShell Community Extensions 2.0

 Data                 [ Skipped ]
 DirectoryServices    [ Skipped ]
 Drawing              [ Skipped ]
 EnvironmentBlock     [ Skipped ]
 FileSystem           [ Skipped ]
 Math                 [ Loaded  ]
 Messaging            [ Skipped ]
 Net                  [ Loaded  ]
 ObjectHelp           [ Skipped ]
 SIUnits              [ Skipped ]
 TabExpansion         [ Skipped ]
 TerminalServices     [ Skipped ]
 Text                 [ Loaded  ]
 UIAutomation         [ Skipped ]
 Vhd                  [ Skipped ]
 Wmi                  [ Skipped ]
 Xml                  [ Skipped ]

I have a strongly-typed a flags enum [pscx.pscxmodules] in pscx.dll which I use in this module, and might have a use for in future plans. The pscx.psd1 loads this via a RequiredAssemblies call which loads the assembly without importing cmdlets/providers. I'm not sure if I want to keep this going forward, but it might come in handy.

I also added my ObjectHelp get-help -object  function proxy as Pscx.ObjectHelp.psd1/psm1.

The loader emits status messages for nested modules in the style of the linux kernel modules. I'll add a "quiet" switch later. Please let me know your thoughts, and I've no problem binning the lot if you hate it. ;-)


(of course, if you omit args, it loads all modules in modules\ careful to only load a psd1 if a psm1 exists, or the psm1 if no psd1 exists).

Oct 7, 2009 at 5:12 PM

Oh, and an invalid use gives us:

PS C:\projects\PowerShell\Pscx\Trunk\Src\Pscx\bin\debug> ipmo .\pscx.psd1 -args foo,bar -force
WARNING: Invalid module(s) specified. Accepted values: Data, DirectoryServices, Drawing, EnvironmentBlock, FileSystem,
Math, Messaging, Net, ObjectHelp, SIUnits, TabExpansion, TerminalServices, Text, UIAutomation, Vhd, Wmi, Xml.
WARNING: Please run 'remove-module pscx' and try again.

Oct 7, 2009 at 5:20 PM

One more thing - currently ObjectHelp eagerly caches help for mscorlib and system; I'll change that to cache on first use - currently it slows down the pscx loading process.

Oct 7, 2009 at 5:39 PM

The bit about not slowing down PSCX module loading is important for folks that load PSCX in their profile.  We should be striving to keep load time very short. 

Regarding the new approach, I haven't looked at the code yet but I like it.  Perhaps if you specify no arguments it displays no loading output i.e. quiet.

Now what do you think about the granurality of all these modules?  I'm still concerned a bit about long term maintenance (like I'm finding cmdlets that are missing because they were never exported). 

>> while also suppressing the "warning non-standard verbs" messages.

I like that.  Shouldn't Tail be a standard verb?  :-)

Oct 7, 2009 at 5:57 PM

Yeah I'm thinking that if you just exec "ipmo pscx", it should load all the modules.

Oct 7, 2009 at 6:01 PM

BTW to what level do we test the combinations of loaded modules?  That's a lot of combinations.  I know they should work independently of each other but ...

Oct 7, 2009 at 6:33 PM
Edited Oct 7, 2009 at 6:35 PM

Ok, just checked in:

* objecthelp module defers caching mscorlib/system help until first use of objecthelp parameterset;
* import-module pscx - now defaults to quiet load if no submodules specified via -args

Re: combinations - that is a possible use of the [pscx.pscxmodules] flags enum - it's availabl in each nested module. We could write a module-scope function created in the root pscx.psm1 module - Requires-PscxModule? - that could be called in the nested module?... hmm. Then load order becomes important.

Edit: Having said that, strictly speaking the modules can be given access to the entirety of our exported binary Cmdlets, yet not export them to user land. Madness, eh?


Oct 7, 2009 at 6:36 PM
Edited Oct 10, 2009 at 1:40 AM
I think the modules should be independent.
Oct 7, 2009 at 6:48 PM
Edited Oct 7, 2009 at 6:49 PM

Agreed - it should be possible to do.

Urgh, the more I look at my usage of that static enum [pscx.pscxmodules], the more I need to get rid of it. It's actually a circular dependency of sorts. That's it, I'll kill that. I can do this in pure script.

Oct 8, 2009 at 1:37 AM

>> I think the modules should be independent.

I agree they should be.  The problem occurs when they're accidentally not independent.  It's a bit harder to test that.

Oct 9, 2009 at 2:21 AM

No, no, PowerShell ALREADY has support for modules being dependent on each other, don’t be writing a requires cmdlet. ;)

Oct 9, 2009 at 2:36 AM
It kinda does, but it's not very reliable.

On Thu, Oct 8, 2009 at 9:21 PM, Jaykul <notifications@codeplex.com> wrote:

From: Jaykul

No, no, PowerShell ALREADY has support for modules being dependent on each other, don’t be writing a requires cmdlet. ;)

Read the full discussion online.

To add a post to this discussion, reply to this email (Pscx@discussions.codeplex.com)

To start a new discussion for this project, email Pscx@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


404 signature missing
Oct 9, 2009 at 2:41 AM
In what circumstances is Import-Module unreliable with nested modules? Or do you mean the "RequiredModules" property?
I agree with Jaykul that we should use standard infrastructure whenever possible.
Oct 9, 2009 at 2:51 AM
I agree too - it was just a general comment that RequiredModules has no concept of "strong" identity (e.g. the GUID in the PSD1) - it only accepts the string name, e.g. "pscx." (which is pretty weak as far as identity goes)

On Thu, Oct 8, 2009 at 9:41 PM, jachymko <notifications@codeplex.com> wrote:

From: jachymko

In what circumstances is Import-Module unreliable with nested modules? Or do you mean the "RequiredModules" property?
I agree with Jaykul that we should use standard infrastructure whenever possible.

Read the full discussion online.

To add a post to this discussion, reply to this email (Pscx@discussions.codeplex.com)

To start a new discussion for this project, email Pscx@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


404 signature missing