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
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:\>
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 :