help to output array

This topic contains 8 replies, has 3 voices, and was last updated by  jep 3 years, 11 months ago.

  • Author
    Posts
  • #9950

    jep
    Participant

    first of all, sorry for my english...

    hello all, thanks for all your help in advance, im trying to list speceifc services in specific servers.
    this is part of a procedure where i try to check service status before shutdown these 3 servers.-

    ——————————————————————-
    script
    ——————————————————————-
    function Get-ServicesStatus{
    [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')]
    param(
    $array = @(
    ("ComputerName","ServiceName"),
    ("server01","service01"),
    ("server01","service02"),
    ("server01","service03"),
    ("server01","service04"),
    ("server02","service05"),
    ("server02","service06"),
    ("server02","service07"),
    ("server03","service08")
    )
    )
    Begin{}
    Process
    {
    $out = @() #tried with or without it
    for ($i = 1; $i -lt 9; $i++)
    { $out=Get-Service -ComputerName $array[$i][0] -Name $array[$i][1] |Format-Table -Property MachineName,Status,DisplayName -AutoSize
    }
    Write-Output "————op1"
    $out
    Write-Output "————op2"
    $out[0]
    $out[1]
    $out[2]
    $out[3]
    $out[4]
    $out[5]
    $out[6]
    $out[7]
    $out[8]
    Write-Output "————op3"
    foreach ($element in $out) {$element}
    }
    End{}
    }

    ——————————————————————-
    output
    ——————————————————————-
    ————op1
    MachineName Status DisplayName
    ———– —— ———–
    server03 Running service08

    ————op2
    MachineName Status DisplayName
    ———– —— ———–
    server03 Running service08

    ————op3
    MachineName Status DisplayName
    ———– —— ———–
    server03 Running service08

    ——————————————————————-
    i wish
    ——————————————————————-
    MachineName Status DisplayName
    ———– —— ———–
    server01 status service01
    server01 status service02
    server01 status service03
    server01 status service04
    server02 status service05
    server02 status service06
    server02 status service07
    server03 status service08

    could be possible???

  • #9951

    Richard Siddaway
    Moderator

    There are a number of problems with your script including:
    – the array structure you've used doesn't work
    – you've used format-table and then tried to access the results which is what is giving you the odd looking results
    – you're making multiple trips to the server

    You could put the server & service information into a CSV file but that makes dealing with the services a bit more difficult.
    I'd start by trying something like this

    $servers = "server02", "exch10"
    $server02_services = "BITS", "NtFrs", "MSMQ", "Kdc"
    $exch10_services = "MSExchangeAB", "W32Time", "W3SVC"

    foreach ($server in $servers){
    Get-Service -ComputerName $server -Name (Get-Variable -Name ($server + "_services")).value |
    select @{N="Server"; E={$server}}, Status, Name, DisplayName
    }

    Create a list of servers
    Create a list of services for each server
    loop through the servers using foreach
    use get-service
    – – the -computername comes for the foreach variable
    – – use the server name & add _services to get the variable containing the list of services
    use select to create a calculated field for the computername

    hope this helps

  • #9953

    Rob Simmers
    Participant

    Another option is to create a custom PSObject:

    $data = @()
     
    $data += New-Object –TypeName PSObject -Property `
            (@{'ComputerName'="server10"; 
                'Name'= @("Spooler", "Server", "Workstation");})
    
    $data += New-Object –TypeName PSObject -Property `
            (@{'ComputerName'="exch10"; 
                'Name'= @("BITS", "NtFrs", "MSMQ", "Kdc");})
    
    
    $data | Get-Service | Select MachineName, Name, DisplayName, Status
    

    Additionally, if you would like to keep the data source in another file you can export the above to an XML file (CSV will not hold the object [array] type):

    $data | Export-CliXML C:\Temp\test.xml
    

    and then you can do something like this:

    $xmlData = Import-Clixml C:\Temp\test.xml
    $xmlData  | Get-Service | Select MachineName, Name, DisplayName, Status
    
  • #9955

    Richard Siddaway
    Moderator

    I like that approach – its very neat

  • #9956

    Richard Siddaway
    Moderator

    Another option using hash tables instead of PSObjects


    $data = @{
    "server02" = "BITS", "NtFrs", "MSMQ", "Kdc";
    "exch10" = "MSExchangeAB", "W32Time", "W3SVC"
    }

    foreach ($server in $data.Keys){
    Get-Service -ComputerName $server -Name ($data[$server]) |
    select @{N="Server"; E={$server}}, Status, Name, DisplayName
    }

    Greatest thing about PowerShell is that you get options

  • #9985

    jep
    Participant

    @Richard Siddaway, thank you, im actually working on your idea. i have modified my script and tried using -whatif and seems to be ready for QAS.
    YES RICHARD, SEEMS TO BE SEVERAL WAYS TO SOLVE SAME ISSUE... SO I THINK EVERYTHING IS DECIDED BY PERFORMANCE AND OPTIONS

    @Rob Simmers, thank you too, i will try yours later... seems to be a little advance for me at this time...

    could you guys share some reference site/stuff/link whatever about working with powershell+sql & powershell+oracle, i need simply check that some databases are open and ready before start app service.

    THANK YOU FOR ALL YOUR HELP.

    IT WAS VERY EDUCATED.

  • #9986

    Richard Siddaway
    Moderator

    PowerShell & SQL Server isn't a topic that's been covered very well so far. I haven't seen a book that I would be prepared to recommend. There is a chapter on accessing data from SQL Server in PowerShell in Practice (www.manning.com/siddaway) & we cover working with databases in PowerShell in Depth (http://www.manning.com/jones2/). I've not seen much at all on PowerShell & Oracle.

    before tackling either of the above books I'd recommend you work through Learning PowerShell in a Month of Lunches (http://www.manning.com/jones3/)

  • #10008

    Rob Simmers
    Participant

    Jep,

    The example code I provided leverages how the Get-Service cmdlet was built. If you run Get-Help Get-Service -Full and look at the parameters you're using. Both ComputerName and Name accept string arrays (i.e. string[]) and Accept pipeline input. So, if you wanted to check the SAME services on 3..4..5.. servers, you could do:

    Get-Service -ComputerName "Server01" "Server02", "Server03" -Name "service1", "service2", "service3"
    

    This would go through each server and get the status of each service on that server. The Accept pipeline input allows you to build a PSObject with the ComputerName and Name properties and the cmdlet will absorb and loop through each string array. So, by passing the parameters over the pipeline the cmdlet knows how to process the passed data. When you start building functions, you will get a better understanding how exactly the cmdlet is built and leverage the pipeline.

    As far as checking SQLconnections, if you are just checking to see if you can connect, you should be able to something like:

    $conn=new-object System.Data.SqlClient.SQLConnection
    $ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerInstance,$Database,$ConnectionTimeout
    $conn.ConnectionString=$ConnectionString
    Try {
        #Attempt to open a connection to the database
        $conn.Open()
        $conn.Close()
        (Get-Service -Name "blah").Start
    }
    Catch {
        "Could not connect to SQL server"
    }
    

    Oracle is more convoluted, you typically need to be connecting to Oracle with a particular driver for the version of the database. This typically means you need to install a Oracle client on the system you are connecting from and reference the appropriate ODBC driver to connect. Other than that, you could use a similar method using System.Data.OracleClient

  • #10018

    jep
    Participant

    [quote=10008]Jep,
    The example code I provided leverages how the Get-Service cmdlet was built. If you run Get-Help Get-Service -Full and look at the parameters you’re using. Both ComputerName and Name accept string arrays (i.e. string[]) and Accept pipeline input. So, if you wanted to check the SAME services on 3..4..5.. servers, you could do:

    Get-Service -ComputerName "Server01" "Server02", "Server03" -Name "service1", "service2", "service3"
    

    This would go through each server and get the status of each service on that server. The Accept pipeline input allows you to build a PSObject with the ComputerName and Name properties and the cmdlet will absorb and loop through each string array. So, by passing the parameters over the pipeline the cmdlet knows how to process the passed data. When you start building functions, you will get a better understanding how exactly the cmdlet is built and leverage the pipeline.
    [/quote]
    @Rob Simmers,THANK YOU!
    i've tried it x 3 (one for each server) but as you can see in script i need to stop/start differents services en each server so it doesn't work for me. Actually im ussing Richard ideas and it is working fine for me.

    now i will start working on you advice about sql. THANK YOU.

    @Richard Siddaway, THANK YOU, i will get recommended books. I thik i will start with " Learning PowerShell in a Month" in order to be guided.

You must be logged in to reply to this topic.