locked
For Each loop and if statement RRS feed

  • Question

  • I am trying to do a script that looks at a .csv file reads the list of "servers and "services" on that server and if its notice any that is stopped it sends us a email.  If not it does nothing.

               




    $list = Import-Csv C:\Users\dyoungblood\Desktop\1.csv
     
    Foreach ($Server in $list)
    {
      Invoke-Command –computername $server.server  –scriptblock{ 

          
          $servicecheck = Get-Service –name $list.service
         
         If ($servicecheck -eq "Stopped")

            { 
        
                 Start-Service $list.service
                 $From = "serversareus@fbhl.com"
                 $To =  "dyoungblood@fbhl.com" 
                 $Subject = "Service on this device has been started"
                 $Body = ""
                 $SMTPServer = "smtp.sendgrid.net" 
                 $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
                 $SMTPClient.EnableSsl = $true 
                 $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("apikey", "0"); 
                 $SMTPClient.Send($From, $To, $Subject, $Body)

            }


         

    }

    my script looks like this  above...do I have something in the wrong location because this seem to run with no errors just exist the script and does nothing?  I am new to powershell so bare with me.  Let me know if you need anything else from me

    ok what about this? should there be another close bracket after scriptblock?


    • Edited by ES3536 Monday, October 2, 2017 8:17 PM
    Friday, September 29, 2017 2:26 PM

Answers

  • First you need to spend some time learning PowerShell and also learning how to format and post code so that it is readable.

    If you build code correctly you will be able to easily see you mistakes.

    $From = "serversareus@fbhl.com"
    $To = "dyoungblood@fbhl.com"
    $SMTPServer = "smtp.sendgrid.net"
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
    $SMTPClient.EnableSsl = $true
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("apikey", "0");
    
    $csv = Import-Csv C:\Users\dyoungblood\Desktop\1.csv
    Foreach ($item in $csv) {
    	$srvc = Get-Service –name $item.service -ComputerName $item.server
    	If ($srvc.Status -eq 'Stopped') {
    		$srvc | Start-Service
    		$SMTPClient.Send($From, $To, "Service on $($item.server) has been started", "")	
    	}
    }


    \_(ツ)_/



    • Edited by jrv Tuesday, October 3, 2017 1:12 PM
    • Marked as answer by ES3536 Thursday, October 5, 2017 7:38 PM
    Tuesday, October 3, 2017 1:11 PM
  • You cannot learn programming by trial and error.  It is impossible.  Those that think they have usually end up stuck or doing damage.  It is also the slowest way to learn anything.

    There are many good books that teach the basics.  The time spent with a tutorial will reapy itself a hundred fold

    Here is a good introductory video course:

    Learn PowerShell: https://mva.microsoft.com/en-us/training-courses/getting-started-with-microsoft-powershell-8276<o:p></o:p>



    \_(ツ)_/

    • Marked as answer by ES3536 Thursday, October 5, 2017 7:37 PM
    Tuesday, October 3, 2017 5:11 PM

All replies

  • Hi,

    basically, you never retrieve the service you want to process (Get-Service servicename -ComputerName $Server). Thus the if-clause is always false and you execute else.

    There is no point to set execution policy in the script - either the policy allows execution, or your script wouldn't be running anyway.

    Rather than messing up a .NET smtp client, try using Send-MailMessage (Run Get-Help Send-MeilMessage -Examples to see how it is used).

    Your else doesn't really serve a purpose. Drop it entirely - the script will end when it has processed all servers, all on its own.

    Cheers,
    Fred


    There's no place like 127.0.0.1


    • Edited by FWN Friday, September 29, 2017 2:32 PM
    Friday, September 29, 2017 2:32 PM
  • Hi,

    I agreed with FWN.

    In addition, since Start-Service cmdlet does not have the -ComputerName parameter, I recommend you could have a try with the .Start() method, the following scripts for your reference. Hope it is helpful to you:
    $lists = Import-Csv -Path 'C:\1.csv'
    foreach ($list in $lists)
    {
        $service = Get-Service -ComputerName $list.servername -Name $list.servicename
        if ($service.Status -ne 'Running')
        {
            $service.Start()
            Send-MailMessage ...
        }
    } 

    If you need further help, please feel free to let us know.

    Best Regards,
    Albert Ling

    Please remember to mark the replies as an answers if they help and unmark them if they provide no help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com.

    Monday, October 2, 2017 5:29 AM
  • $list = Import-Csv C:\Users\dyoungblood\Desktop\1.csv
     
    Foreach ($Server in $list)
    {
      Invoke-Command –computername $server.server  –scriptblock{ 

          
          $servicecheck = Get-Service –name $list.service
         
         If ($servicecheck -eq "Stopped")

            { 
        
                 Start-Service $list.service
                 $From = "serversareus@fbhl.com"
                 $To =  "dyoungblood@fbhl.com" 
                 $Subject = "Service on this device has been started"
                 $Body = ""
                 $SMTPServer = "smtp.sendgrid.net" 
                 $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
                 $SMTPClient.EnableSsl = $true 
                 $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("apikey", "0"); 
                 $SMTPClient.Send($From, $To, $Subject, $Body)

            }


         

    }

    I am trying this where do I close the bracket after the scriptblock?

    Tuesday, October 3, 2017 1:02 PM
  • $list = Import-Csv C:\Users\dyoungblood\Desktop\1.csv
     
    Foreach ($Server in $list)
    {
      Invoke-Command –computername $server.server  –scriptblock{ 

          
          $servicecheck = Get-Service –name $list.service
         
         If ($servicecheck -eq "Stopped")

            { 
        
                 Start-Service $list.service
                 $From = "serversareus@fbhl.com"
                 $To =  "dyoungblood@fbhl.com" 
                 $Subject = "Service on this device has been started"
                 $Body = ""
                 $SMTPServer = "smtp.sendgrid.net" 
                 $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
                 $SMTPClient.EnableSsl = $true 
                 $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("apikey", "0"); 
                 $SMTPClient.Send($From, $To, $Subject, $Body)

            }


         

    }

    the smtp is working to send the email will the send-mailmessage cut down on some of the extra stuff or something? Also after the scriptblock where do I close that bracket?

    Tuesday, October 3, 2017 1:05 PM
  • First you need to spend some time learning PowerShell and also learning how to format and post code so that it is readable.

    If you build code correctly you will be able to easily see you mistakes.

    $From = "serversareus@fbhl.com"
    $To = "dyoungblood@fbhl.com"
    $SMTPServer = "smtp.sendgrid.net"
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
    $SMTPClient.EnableSsl = $true
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("apikey", "0");
    
    $csv = Import-Csv C:\Users\dyoungblood\Desktop\1.csv
    Foreach ($item in $csv) {
    	$srvc = Get-Service –name $item.service -ComputerName $item.server
    	If ($srvc.Status -eq 'Stopped') {
    		$srvc | Start-Service
    		$SMTPClient.Send($From, $To, "Service on $($item.server) has been started", "")	
    	}
    }


    \_(ツ)_/



    • Edited by jrv Tuesday, October 3, 2017 1:12 PM
    • Marked as answer by ES3536 Thursday, October 5, 2017 7:38 PM
    Tuesday, October 3, 2017 1:11 PM
  • Well I am a beginner still learning alot here...so what is wrong with putting it in the order I had?  Basically in order of how I was thinking. Read the list of servers and services then if the services is stopped send a email if not do nothing?
    Tuesday, October 3, 2017 4:26 PM
  • Take some time to learn PowerShell and you will understand why I did what I did.

    It eliminates remoting and is simple and easy to understand, debug and run.

    You don't need to constantly reassign static values inside your loop.  It serves no purpose and is inefficient.

    This is the only active code.  The rest is just setup.

    Foreach ($item in $csv) {
    	$srvc = Get-Service –name $item.service -ComputerName $item.server
    	If ($srvc.Status -eq 'Stopped') {
    		$srvc | Start-Service
    		$SMTPClient.Send($From, $To, "Service on $($item.server) has been started", "")	
    	}
    }


    \_(ツ)_/

    Tuesday, October 3, 2017 4:36 PM
  • ok so whats a good source to learn PowerShell besides just trial and error?

    Tuesday, October 3, 2017 5:06 PM
  • You cannot learn programming by trial and error.  It is impossible.  Those that think they have usually end up stuck or doing damage.  It is also the slowest way to learn anything.

    There are many good books that teach the basics.  The time spent with a tutorial will reapy itself a hundred fold

    Here is a good introductory video course:

    Learn PowerShell: https://mva.microsoft.com/en-us/training-courses/getting-started-with-microsoft-powershell-8276<o:p></o:p>



    \_(ツ)_/

    • Marked as answer by ES3536 Thursday, October 5, 2017 7:37 PM
    Tuesday, October 3, 2017 5:11 PM
  • Thanks will do..I will check it out now.
    Tuesday, October 3, 2017 5:16 PM
  • Hi,

    I'm checking how the issue is going, was your issue resolved?

    And if the replies as above are helpful, we would appreciate you to mark them as answers, and if you resolve it using your own solution, please share your experience and solution here. It will be greatly helpful to others who have the same question.

    Appreciate for your feedback.

    Best Regards,
    Albert Ling

    Please remember to mark the replies as an answers if they help and unmark them if they provide no help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com.

    Wednesday, October 4, 2017 9:15 AM
  • Well I am still looking at some videos to get a better understanding of things.  I am still confused about why we remove the "Invoke-Command –computername $server.server  –scriptblock{" part that Jrv suggested but like I said I am still looking through the videos its some great stuff in there.  Let me try what he had listed and I will let you know.
    Thursday, October 5, 2017 5:57 PM
  •  $From = "serversareus@fbhl.com" 
        $To =  "dyoungblood@fbhl.com" 
        $SMTPServer = "smtp.sendgrid.net" 
        $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
        $SMTPClient.EnableSsl = $true 
        $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("apikey", "0"); 




        $list = Import-Csv C:\Users\dyoungblood\Desktop\1.csv

        Foreach ($server in $list) {

        Invoke-Command –computername $server.server  –scriptblock{


          $servicecheck = Get-Service –name $list.service 

         If ($servicecheck -eq "Stopped"){Start-Service $list.service}


                 $SMTPClient.Send($From, $To, "Service on $($server.server) has been started", "")


            }

        }

    From my list I am getting this error:

    You cannot call a method on a null-valued expression.
        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull
        + PSComputerName        : FBIT10

    Invoke-Command : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again

    If I place this line in its looking locally not in both places local and remote

    $servicecheck = Get-Service –name $list.service -ComputerName $server.Server

                                                              
    Thursday, October 5, 2017 6:41 PM
  • Or this:

    $splat = @{
    	From = "serversareus@fbhl.com"
    	To = "dyoungblood@fbhl.com"
    	SMTPServer = "smtp.sendgrid.net"
    	UseSsl = $true
    	Credentials = [pscredential]::New('apikey',(ConvertTo-SecureString -AsPlainText -String '0' -Force))
    }
    
    $csv = Import-Csv C:\Users\dyoungblood\Desktop\1.csv
    Foreach ($item in $csv) {
    	$srvc = Get-Service –name $item.service -ComputerName $item.server
    	If ($srvc.Status -eq 'Stopped') {
    		$srvc | Start-Service
    		Send-MailMessage -Subject "Service on $($item.server) has been started" @splat
    	}
    }


    \_(ツ)_/

    Thursday, October 5, 2017 7:49 PM
  • $s = @{

        $From = "serversareus@fbhl.com" 
        $To =  "dyoungblood@fbhl.com" 
        $SMTPServer = "smtp.sendgrid.net" 
        #$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
        $SMTPClient.EnableSsl = $true 
        #$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("apikey", "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"); 
        $SMTPClient.Credentials = [pscredential]::new('apikey'),(ConvertTo-SecureString -AsPlainText -String '0' -Force)

    }    

        $list = Import-Csv C:\Users\dyoungblood\Desktop\1.csv

        Foreach ($server in $list) {

        #Invoke-Command –computername $server.server  –scriptblock{


          $servicecheck = Get-Service –name $list.service -ComputerName $server.server

         If ($servicecheck -eq "Stopped"){$servicecheck | Start-Service $list.service


                 Send-MailMessage -Subject "Service on $($server.server) has been started" @s


            }


    }

    Its still looking on my local pc which as a test I do have my local pc in the server list but its giving me this error:

    Get-Service : Cannot find any service with service name 'FicsLongRunningService'.
    At C:\Untitled7.ps1:20 char:23
    + ... vicecheck = Get-Service –name $list.service -ComputerName $server.ser ...
    +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (FicsLongRunningService:String) [Get-Service], ServiceCommandException
        + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand
     
    Get-Service : Cannot find any service with service name 'MicrosoftDynamicsNavServer$DynamicsNAV90'.
    At C:\Untitled7.ps1:20 char:23
    + ... vicecheck = Get-Service –name $list.service -ComputerName $server.ser ...
    +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (MicrosoftDynamicsNavServer$DynamicsNAV90:String) [Get-Service], ServiceCommandException
        + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand
     
    Get-Service : Cannot find any service with service name 'PRTGCoreService'.
    At C:\Untitled7.ps1:20 char:23
    + ... vicecheck = Get-Service –name $list.service -ComputerName $server.ser ...

                                                     
    Friday, October 6, 2017 2:03 PM
  • You managed to take perfectly good code and totally trash it. You need to learn PowerShell before trying to do this.

    \_(ツ)_/

    Friday, October 6, 2017 2:10 PM