Author Posts

June 1, 2017 at 3:45 pm

I am in the process of learning PowerShell and there is a little something that I dont understand with custom object.

First, if I create a variable this way :

 $service = Get-Service -name w32time 

The variable will be populate with few property, the default will be Status, Name, DisplayName
If I pipe it to Get-Member I can see that I have a ServiceController object. I can re-use it to pipe or as a cmdlet parameter. Example :

$Service | stop-service

or

stop-service -input-object $service

I had the -input-object to be sure witch parameter set the cmdlet will use.

Now just for the purpose of my question, let create a custom object:

$myobject = new-object System.Management.Automation.PSObject
$myobject | Add-Member -Value "W32time" -Name "Name" -MemberType NoteProperty
$myobject | Add-Member -Value "Stopped" -Name "Status" -MemberType NoteProperty
$myobject | Add-Member -Value "Windows Time" -Name "DisplayName" -MemberType NoteProperty
$myobject.PSObject.TypeNames.insert(0,"System.ServiceProcess.ServiceController")

With this custom object, I can use it with the pipe only:

$myobject | stop-service

This will not work :

 stop-service -inputobject $myobject

I get this error message : Stop-Service : cannot bind argument to parameter 'name' because it is an empty string

But this will work :

stop-service -inputobject $myobject.name

Why do I need to add .name when working with custom object, Is there anything that I dont do properly, do my custom object is missing something.
I can work around but I would like to understand.

Thank in advance

June 2, 2017 at 2:14 pm

I think because real service object not just Status, Name, DisplayName

PS C:\> get-service w32time | gm

   TypeName: System.ServiceProcess.ServiceController

Name                      MemberType    Definition
----                      ----------    ----------
Name                      AliasProperty Name = ServiceName
RequiredServices          AliasProperty RequiredServices = ServicesDependedOn
Disposed                  Event         System.EventHandler Disposed(System.Object, System.EventArgs)
Close                     Method        void Close()
Continue                  Method        void Continue()
CreateObjRef              Method        System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
Dispose                   Method        void Dispose(), void IDisposable.Dispose()
Equals                    Method        bool Equals(System.Object obj)
ExecuteCommand            Method        void ExecuteCommand(int command)
GetHashCode               Method        int GetHashCode()
GetLifetimeService        Method        System.Object GetLifetimeService()
GetType                   Method        type GetType()
InitializeLifetimeService Method        System.Object InitializeLifetimeService()
Pause                     Method        void Pause()
Refresh                   Method        void Refresh()
Start                     Method        void Start(), void Start(string[] args)
Stop                      Method        void Stop()
WaitForStatus             Method        void WaitForStatus(System.ServiceProcess.ServiceControllerStatus desiredStatus), void ...
CanPauseAndContinue       Property      bool CanPauseAndContinue {get;}
CanShutdown               Property      bool CanShutdown {get;}
CanStop                   Property      bool CanStop {get;}
Container                 Property      System.ComponentModel.IContainer Container {get;}
DependentServices         Property      System.ServiceProcess.ServiceController[] DependentServices {get;}
DisplayName               Property      string DisplayName {get;set;}
MachineName               Property      string MachineName {get;set;}
ServiceHandle             Property      System.Runtime.InteropServices.SafeHandle ServiceHandle {get;}
ServiceName               Property      string ServiceName {get;set;}
ServicesDependedOn        Property      System.ServiceProcess.ServiceController[] ServicesDependedOn {get;}
ServiceType               Property      System.ServiceProcess.ServiceType ServiceType {get;}
Site                      Property      System.ComponentModel.ISite Site {get;set;}
StartType                 Property      System.ServiceProcess.ServiceStartMode StartType {get;}
Status                    Property      System.ServiceProcess.ServiceControllerStatus Status {get;}
ToString                  ScriptMethod  System.Object ToString();

PS C:\> (get-service w32time) -is 'System.ServiceProcess.ServiceController'
True
PS C:\> $myobject -is 'System.ServiceProcess.ServiceController'
False
PS C:\> (get-service w32time) -as 'System.ServiceProcess.ServiceController'

Status   Name               DisplayName
------   ----               -----------
Running  w32time            Служба времени Windows

PS C:\> $myobject -as 'System.ServiceProcess.ServiceController'
PS C:\>

June 2, 2017 at 3:10 pm

Your input object is not the same as a service.
So it just cant match it.

Powershell has a format it shows you, but there is more to the services than it show with the standard command.

    GET-SERVICE W*|SELECT -First 1|FL *

    Name : W32Time
    RequiredServices : {}
    CanPauseAndContinue : False
    CanShutdown : True
    CanStop : True
    DisplayName : Windows Time
    DependentServices : {}
    MachineName : .
    ServiceName : W32Time
    ServicesDependedOn : {}
    ServiceHandle : SafeServiceHandle
    Status : Running
    ServiceType : Win32ShareProcess
    Site :
    Container :