MSDN Magazine - December 2007 - (Page 75) You really shouldn’t throw an exception in a cmdlet. Instead, ThrowTerminatingError allows you to stop the execution of the pipeline and provide much more information than you could with an exception. You’ll notice in the code for my cmdlets that I use ThrowTerminatingError in BeginProcessing but then use WriteError in the ProcessRecord methods. This is because if I can’t get access to the IsolatedStorage, there’s not much I’ll be able to do with regard to the operation of the cmdlet in general. However, if I encounter an error while reading the file, I may be able to recover and continue. Figure 6 IsolatedStorageBase Base Class public class IsolatedStorageBase : PSCmdlet { [Parameter] public string Name } [Cmdlet(VerbsCommon.Set, “IsolatedStorageData”,SupportsShouldProcess = true)] public class SetIsolatedStorageDataCommand: IsolatedStorageBase { } [Cmdlet(VerbsCommon.Get, “IsolatedStorageData”)] public class GetIsolatedStorageDataCommand: IsolatedStorageBase { } [Cmdlet(VerbsCommon.Remove,”IsolatedStorageFile”,SupportsShouldProcess = true)] public class RemoveIsolatedStorageFileCommand: IsolatedStorageBase { } Troubleshooting Messages Windows PowerShell provides a number of ways to communicate with the user. There are three methods you can use to notify the user when you want to communicate something that isn’t a result or an error. You should know that when you use these methods, you can’t redirect the messages that will be sent, but you can suppress them by setting some preferences in the shell. These methods communicate directly with the hosting application, in this case PowerShell.exe, and in turn write to the console window. Preference variables offer a variety of behaviors, from not writing anything to asking whether the message should be written before continuing. I use these in my sample cmdlets a little more than you might because I want to show how they can help. If you have complicated code that needs more than just error or results, be sure to use these available methods. The last thing you want to do is use something like System.Console.WriteLine from a cmdlet. First, it’s pretty bad practice and second, you shouldn’t depend on the hosting application since the console may not even be present. You should use WriteVerbose if you have extra out-of-band information you want to pass to the user. This isn’t for developer messages; it’s for letting your user know what’s going on under the covers. The interface is pretty simple. Here’s an example from my Remove-IsolatedStorageFile, which uses WriteVerbose to output that it’s about to remove the IsolatedStorage file: if(ShouldProcess(“Remove Isolated Storage”)) { WriteVerbose(“Deleting Isolated Storage: “ + Name); isoStore = this.GetMyStore(); isoStore.DeleteFile(Name); } Cmdlet Groups All three of my cmdlets pertain to IsolatedStorage, so the nouns all have the same root: IsolatedStorage. Two of the cmdlets are for working with the actual data (Set-IsolatedStorageData and GetIsolatedStorageData) while the other removes the file (RemoveIsolatedStorageFile). Since all of these cmdlets have a parameter in common (the name of the actual file that will be used), I don’t have to implement the same parameter in all of the cmdlets. Instead, I can create a base class, IsolatedStorageBase, that derives from PSCmdlet, and the cmdlets will derive from IsolatedStorageBase (see Figure 6). This is a good way to ensure that you are consistent from Preference variables cmdlet to cmdlet. Creating a Snap-In You use WriteDebug when you want to communicate with developers, giving them a chance to troubleshoot errant behavior in your cmdlet. Typically, you would attach a debugger to the system, but you can’t always do that in the field. WriteDebug will help in these situations. WriteWarning is yet another way to communicate with the user, providing information about the execution of your cmdlet. (I haven’t used this method in my sample cmdlets.) A good example of using WriteWarning is if you want to change the behavior of a cmdlet over time. You can use WriteWarning, for instance, if you were to deprecate a parameter and wanted to tell the user to stop using it in favor of a new parameter. In order to use these new cmdlets, you need to add them to the Windows PowerShell environment. Windows PowerShell has the ability to dynamically add cmdlets to the session via a snapin. To avoid potential confusion with MMC snap-ins, a Windows PowerShell snap-in is called a PSSnapIn. To create a PSSnapIn, you need to write a bit of code that will perform two tasks. First, it provides identification for your snapin so it can be distinguished from other snap-ins installed on your system. Second, it provides information for properly installing the snap-in and for creating the appropriate registry entries to allow Windows PowerShell to find the assembly. There are two types of Windows PowerShell snap-ins in the System.Management.Automation namespace: PSSnapIn and CustomPSSnapIn. You should use PSSnapIn when you want to register all the cmdlets and providers automatically in one assembly. CustomPSSnapIn should be used when you want to register Custom Cmdlets december2007 75 offer a variety of behaviors, from not writing anything to asking whether the message should be written before continuing.
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.