Powershell script issues (uhg)...

the issue, I am attaching the script/server.txt file I m using. I have the first piece working but am completely SOL on second piece. All I m trying to accomplish is.
imports servers.txt (which has 3 fields computername, operation, service)
Look at each server and start the service listed (may not always be w3svc)
then write the status to a log file ... (this part is all working albeit I think the code could work better functionally, but I am not sure what else to do with it)

Second part of the script is doing much the same thing as the first part..
importing servers.txt (which has 3 fields computername, operation, service)  Looks at the path to a remote script as part of the Operation header.

Creates remote session  using new-possession
Creates a var called $script and passes in the file path to the remote machine script location
Uses invoke-command  -Session  and -scriptblock {}  I am trying to use $script inside of the script block with a command for start.  Then I write the output to a log ..

Im thinking there has to be a better way to do this but that is what they want done. Basically they are looking for the ability to start a service or allow other teams to create scripts that will be kicked off remotely by this script.

Again I have to say thanks to everyone for putting up with me, and I hope to make this the last time I have to bother anyone with this.. Anyway after exhausting my books/google I don't seem get it much better than I did starting.    
I am attaching the script and servers.txt as I don't always explain things very well.

thanks


SvcStart.ps1
 Setup trap to catch exceptions
trap [Exception]
{
      write-error $("TRAPPED: " + $_.Exception.Message);
}
$start = $true


#Assuming headers of "computername","operation","service"

$computers = Import-CSV 'C:\scripts\servers.txt'  

foreach($computer in $computers)
{
    write-host $computer.computername $computer.service $computer.operation
    $objWMIService = Get-WmiObject -Class win32_service  -filter "name = '$($computer.service)'"
    if($computer.operation -eq "service")
    {
        if($objWMIService.state -ne "Running")
        {
            $objWMIService.StartService() | Out-Null;
            # Refresh the object instance
            $state = (Get-WmiObject Win32_Service -Filter "Name = '$($computer.service)'" -computer $computer.computername).state
            Write-Output "$($computer.service) is ""$state"" on $($computer.name)" | Out-File C:\scripts\log.txt -append
        }
    }
    elseif($computer.operation -eq "script")
    {        
   
$rmSessions = Import-CSV 'C:\scripts\servers.txt'

foreach($computer in $rmSession)
      {
    #trying to create a new session $session that will be similar to the foreach($computer in $computers) above.
            $session = new-psssession -computername $computer -Sessionoption (New-PSSession -NoMachineProfile)
        #once the session is established then I want to define a var $script $script that would allow me to pass in a path form the servers.txt like c:\scripts\PS.bat
        $script = operation (get-Content #operation script filepath for each machine in the servers.txt
         Invoke-Command -Session $computer -ScriptBlock {}  # I want to add that var $script to the scriptblock with a start or execute command.
         #once the command invoke command is finished I want define a var called $status and write it to the output log.
         $status =
        Write-Output "$($computer.operation) is ""$status"" on $($computer.session)" | Out-File C:\scripts\RMlog.txt -append
   
    }
     




    }
}
svcstartPS1.txt
servers.txt
AjarnJonesyAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

QlemoBatchelor, Developer and EE Topic AdvisorCommented:
Let's see if we are on the same line this time ;-)
trap [Exception]
{
      write-error $("TRAPPED: " + $_.Exception.Message);
}
$start = $true


#Assuming headers of "computername","operation","service" 

$computers = Import-CSV 'C:\scripts\servers.txt'  

foreach($computer in $computers)
{
    write-host $computer.computername $computer.service $computer.operation
    $objWMIService = Get-WmiObject -Class win32_service  -filter "name = '$($computer.service)'"
    if($computer.operation -eq "service")
    {
        if($objWMIService.state -ne "Running")
        {
            $objWMIService.StartService() | Out-Null;
            # Refresh the object instance 
            $state = (Get-WmiObject Win32_Service -Filter "Name = '$($computer.service)'" -computer $computer.computername).state
            Write-Output "$($computer.service) is ""$state"" on $($computer.name)" | Out-File C:\scripts\log.txt -append
        }
    }
    elseif($computer.operation -eq "script")
    {        
	$Status = Invoke-Command -ComputerName $computer.name -ScriptBlock { . $computer.service }
	Write-Output "Script execution status for $($computer.name) is $Status" >> C:\Scripts\RMLog.txt
    }
}

Open in new window

0
AjarnJonesyAuthor Commented:
I
0
AjarnJonesyAuthor Commented:
Yep definitely on the same track... Im cant figure out why I was trying to re-import the txt file..Thanks for the reply ...

For the moment I do have one question that is bothering me though....

The Line (correct me if I am wrong but this is where you define the var values from the header correct.?)   I am wondering if this line:

    $objWMIService = Get-WmiObject -Class win32_service  -filter "name = '$($computer.service)'"

Should be something like this, but if so How do I declare $computer.computername prior that line ( at least I am assuming that I need to define $computer.computername prior to that) so that I don't try to pass in a var with no value?

 $objWMIService = Get-WmiObject -Class win32_service -computer $computer.computername -filter "name = '$($computer.service)'"
0
10 Tips to Protect Your Business from Ransomware

Did you know that ransomware is the most widespread, destructive malware in the world today? It accounts for 39% of all security breaches, with ransomware gangsters projected to make $11.5B in profits from online extortion by 2019.

AjarnJonesyAuthor Commented:
In the the elseif statement.. (in this case I want to run a script on a remote machine) do I need to use something like Pssession to create a session prior to the invoke-command?
0
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
PSSession objects are persistent remote sessions. If you want to execute several different commands, controlled by the local running code, then a PSSession is a good idea.
If you want to apply a single command or script as a whole against a remote machine, no explicit PSSession is needed - it is created, used and discarded automatically. But doing that often needs a lot of time, and that is why you can use explicit PSSessions.
0
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
Regarding the vars, note that you need to define $computer to have properties computername, operation and service. $computer again is defined by the foreach ($computer in $computers), and $computers by import-csv. The latter takes the properties from the CSV file header line.

So, in fact, you are dependent on the proper header line in the CSV, else you access non-existent properties, which are translated to $null values by PowerShell most of the time (which is the origin of many issues with errornous code).

You can add some more reliability to the code by using an explicit header (like in import-csv C:\scripts\servers.txt -header ComputerName, Operation, Service), but that takes the first line of the CSV file over as part of the data, and so this one needs to be ignored, which is why it isn't used often if the header line exists in the CSV.


Caused enough of confusion now?
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
AjarnJonesyAuthor Commented:
I cleaned up the servers.txt a bit with headers that were a bit more explanatory and did the same with the code.. Also added the -header option to the import-csv... Very good idea to have that defined that way. after that I now have it running through importing the list and if a service is listed it tries to start the service. If a file path is listed it moves on to the Elseif and tries to run the remote script..  Thanks for the help that makes a lot more sense..
finished code to this point minus  -Pssession  is as follows..

$computers = Import-CSV 'C:\scripts\servers.txt'  -Header ComputerName, optype, opname

foreach($computer in $computers)
{
    if($computer.optype -eq "Service")
    {
        $objWMIService = Get-WmiObject -Class win32_service  -filter "name = '$($computer.opname)'"

        if($objWMIService.state -eq "Stopped")
        {
            write-host starting $computer.opname on $computer.computername
            $objWMIService.StartService() | Out-Null;
            # Refresh the object instance
            $state = (Get-WmiObject Win32_Service -Filter "Name = '$($computer.opname)'" -computer $computer.computername).state
            Write-Output "$($computer.opname) is ""$state"" on $($computer.name)" | Out-File C:\scripts\log.txt -append
        } else {
            write-host skipping $computer.opname on $computer.computername because it is already running
        }
    }
    elseif($computer.optype -eq "script")
    {      
    write-host  running script $computer.opname on $computer.computername  
      $Status = Invoke-Command -ComputerName $computer.computername -ScriptBlock { . $computer.opname }
      Write-Output "Script execution status for $($computer.name) is $Status" >> C:\Scripts\RMLog.txt
    }
}
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.