resolver101
resolver101

Reputation: 2255

Powershell: How do i create a function for the output of system.object?

im writing a script to get services from local and remote machines. I've had to split the wmi call for local and remote machines (remote machines require different credentials). I want to output them as System.Object. How do i create a function for the output of system.object?

heres the code i have so far:

$objServicecol = @()

    # how do i get AddService object back 
    Function AddServiceObjects
    {
            ForEach ($Service in $Services)
            {
                $objService = New-Object System.Object
                $objService | Add-Member -MemberType NoteProperty -Name SystemName -Value $Services.SystemName 
                $objService | Add-Member -MemberType NoteProperty -Name Name -Value $Services.Name 
                $objService | Add-Member -MemberType NoteProperty -Name StartMode -Value $Services.StartMode
                $objService | Add-Member -MemberType NoteProperty -Name StartName -Value $Services.StartName
                $objService | Add-Member -MemberType NoteProperty -Name Status -Value $Services.Status
                #$objServiceCol += $objService
                AddServiceObjects += $objService
            }
        }

    # Executes local WMI 
    If ($Servers -contains "localhost") 
    {
        $Services = Get-WMIObject Win32_Service -ComputerName "localhost" | Select-Object SystemName, Name, StartMode, StartName, Status
        AddServiceObjects $Services
    }
...#execute remote wmi...

Upvotes: 1

Views: 1145

Answers (3)

Jeffery Hicks
Jeffery Hicks

Reputation: 943

When you pipe to Select-Object you are already getting a PSObject. I don't understand why you feel the need to recreate the object in your function. Just because you have two WMI calls doesn't mean anything. Have each one write to the pipeline. If you need to, add each result to your array and then write the array to the pipeline at the end of your script.

If ($Servers -contains "localhost") 
{
   $objServiceCol+= Get-WMIObject Win32_Service -ComputerName "localhost" | Select-Object SystemName, Name, StartMode, StartName, Status

}
else 
{
  $objServiceCol+= Get-WMIObject Win32_Service -ComputerName $computer -credential $cred | Select-Object SystemName, Name, StartMode, StartName, Status

}
#write final results to the pipeline
$objServiceCol

Upvotes: 0

SpellingD
SpellingD

Reputation: 2621

Uncomment #$objServiceCol += $objService and get rid of AddServiceObjects += $objService.

Then, after the foreach, just do $objServiceCol to get the list to spit out its contents in object format.

Upvotes: 0

Keith Hill
Keith Hill

Reputation: 201832

In .NET, System.Object is the root of the inheritance hierarchy so any type you output can be treated as a System.Object. You might want to consider creating a psobject instead of a System.Object in your loop (and simplify it):

Function AddServiceObjects($Services)
{
    ForEach ($service in $Services)
    {
        New-Object psobject -Property @{
            SystemName = $service.SystemName
            Name       = $service.Name 
            StartMode  = $service.StartMode
            StartName  = $service.StartName
            Status     = $service.Status }
     }
}

Note that by virtue of not assigning the New-Object output to a variable it will get output from the function - one object for every iteration through the loop. Also note that your foreach iteration variable was $service but your were referencing the global $Services in your New-Object command.

Upvotes: 3

Related Questions