PowerShell Remoting Project Home

Thursday, February 16, 2006

Add-ProcessOwner cmdlet (update)

(Added on Mar 6th) There is a follow up post on this topic here.

Rewrite Add-ProcessOwner cmdlet and build into a MshSnapin. Most intersting thing here: Wrap an object into MshObject, add a MshNoteProperty.

MshObject Constructor:
System.Management.Automation.MshObject..ctor(Object)
MshNoteProperty Constructor:
System.Management.Automation.MshNoteProperty..ctor(String, Object)
Example to use this cmdlet:
>$ps=get-process | add-processowner
>$ps | get-member

TypeName: System.Diagnostics.Process

>$ps[0].ProcessOwner | get-member

System.Security.Principal.WindowsIdentity
# Some processOwner could be null due to security policy
//Add-ProcessOwner.cs
using System;
using System.Security.Principal;
using System.Diagnostics;
using System.Management.Automation;
using System.Runtime.InteropServices;

namespace MSHForFun.Security
{
    /// <summary>
    /// Add Process Owner infomation as NoteProperty
    /// </summary>
    [Cmdlet("add", "processowner", SupportsShouldProcess = true)]
    public class AddProcessOwnerCmd : Cmdlet
    {
        #region Parameters
        private Process[] allProcess = null;
        /// <summary>
        /// Arrary of Process to query
        /// </summary>
        [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)]
        public Process[] ProcessArray
        {
            get { return allProcess; }
            set { allProcess = value; }
        }
        #endregion

        private SafeTokenHandle processToken = new SafeTokenHandle(IntPtr.Zero);
        private MshObject psex;
        private MshNoteProperty info;
        private WindowsIdentity id;

        /// <summary>
        /// Get WindowsIdentity for each process
        /// </summary>
        protected override void ProcessRecord()
        {
            foreach (Process ps in allProcess)
            {
                if (ShouldProcess(ps.ProcessName))
                {
                    psex = new MshObject(ps);
                    try
                    {
                        if (Win32Helper.OpenProcessToken(ps.Handle, TokenAccessLevels.Query, ref processToken))
                        {
                            if (processToken.IsInvalid)
                            {
                                WriteWarning("Invalid process token: " + ps.ProcessName);
                                info = new MshNoteProperty("ProcessOwner", null);
                                psex.Properties.Add(info);
                            }
                            else
                            {
                                id = processToken.GetWindowsIdenty();
                                WriteVerbose("Successfully get process owner information: " + ps.ProcessName);
                                info = new MshNoteProperty("ProcessOwner", id);
                                psex.Properties.Add(info);
                            }
                        }
                        else
                        {
                            WriteWarning("Unable to query process token (privilege not held): " + ps.ProcessName);
                            info = new MshNoteProperty("ProcessOwner", null);
                            psex.Properties.Add(info);
                        }
                    }
                    catch
                    {
                        WriteWarning("Unable to query process token (privilege not held): " + ps.ProcessName);
                        info = new MshNoteProperty("ProcessOwner", null);
                        psex.Properties.Add(info);
                    }                   
                    WriteObject(psex);
                }
            }
        }
    }
}
For MshSnapin
//MshSnapin.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation;
using System.Configuration.Install;
using System.ComponentModel;


namespace MSHForFun.Security
{
    /// <summary> Defines the properties of MonadSecurity snapin</summary>
    [RunInstaller(true)]
    public class MonadSecurity : MshSnapIn
    {
        /// <summary>Creates an instance of MonadSecurity Snapin class.</summary>
        public MonadSecurity() : base()
        {
        }
        ///<summary>The snapin name which is used for registration</summary>
        public override string Name
        {
            get
            {
                return "MSHForFun.Security";
            }
        }
        /// <summary>Gets vendor of the snapin.</summary>
        public override string Vendor
        {
            get
            {
                return "http://mshforfun.blogspot.com/";
            }
        }
        /// <summary>Gets description of the snapin. </summary>
        public override string Description
        {
            get
            {
                return "Cmdlets for windows security related jobs";
            }
        }
    }
}


[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]

Tags:       


Comments:

Post a Comment





<< Home