简体   繁体   中英

Function within a Function - Powershell

OK I am going to try to explain this as best as I can. What started out as a simple script has turned into a huge mess and now I cannot figure out how to get it working. I have been coming here for answers for some time so maybe you guys can help.

What I am trying to do is a import a list of systems and check to see if they are online. If they are online they go in one list and if not they go in another.

foreach ($server in $servers) {
    if (Test-Connection $server -Count 1 -ea 0 -Quiet) { 
        Write-Host "$server Is Up" -ForegroundColor Green
        $server | out-file -Append $liveSystems -ErrorAction SilentlyContinue 
    } else { 
        Write-Host "$server Is Down" -ForegroundColor Red
        $server | out-file -Append $inactive -ErrorAction SilentlyContinue  
    }
}

From there I check to see if the application I need installed is on the systems. That is where things start to go off-track. When I run the function to process the $liveSystems file all I get is the last line of the file (or the same system over and over) and not each system as it should be.

function Is-Installed( $program ) {

    $x86 = ((Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall") |
            Where-Object { $_.GetValue( "DisplayName" ) -like "*$program*" } ).Length -gt 0;

    $x64 = ((Get-ChildItem "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall") |
        Where-Object { $_.GetValue( "DisplayName" ) -like "*$program*" } ).Length -gt 0;
}

$program

function process-file1 {

    param($filename)

    Get-Content $filename -PipelineVariable line | ForEach-Object {
      Is-Installed -program "My_Service"
        if (Is-Installed -eq "True") {
            Write-Host "$server has agent installed" -ForegroundColor Green
            $server | Out-File $installed -ErrorAction SilentlyContinue
        }
        else
        {
            Write-Host "$server does not have agent installed" -ForegroundColor Red
            $server | Out-File -Append $notInstalled -ErrorAction SilentlyContinue
        }
    }
}

process-file1 -filename $liveSystems

Once I can get the systems to process through the list of installed and not installed I am trying to take the list of installed systems and check which ones have the service running and which ones do not.

$array = @()            
foreach($i in (gc $installed)) {            
    $svc = Get-Service my_service -ComputerName $i -ea "0"            
    $obj = New-Object psobject -Property @{            
        Name = $svc.name            
        Status = $svc.status            
        Computer = $i            
    }            
    $array += $obj            
}                      
$array | Select Computer,Name,Status | Export-Csv -Path $resultsFile - 
NoTypeInformation

Last but not least I run through that list of running and not running and attempt to start the service on systems that are not running.

function process-CSVfile2 {
    param($filename)
    Import-Csv $filename |
    ForEach-Object -PipelineVariable object {
        if($_.Status -eq "Running") {
            Write-Host "Your Service is currently Running on" $_.Computer
        }
        if($_.Status -eq "Stopped") {
            $serviceName = 'my_service'
            $service = Get-CimInstance Win32_Service -ComputerName $_.Computer -Filter "Name=$serviceName"
            $service.Start()
            $service.WaitForStatus("Started",'00:00:30')
            Start-Sleep 10
        }
    }
}

Several of these blocks run separately but when put together they will not run. I can't seem to get past the second block where it just looks at the same line over and over.

In addition there is a piece I have been trying to get working that would install the application on systems that do not have the service installed but that is not working either but I will save that for a different time.

If anyone can help me with this I would really appreciate it. After 3 days of trying to get it running I am at my wits end.

I'd create objects and properties instead of files with computers online etc... Something like:

$Computers=New-Object -TypeName System.Collections.ArrayList
$Servers = @(Get-Content -path c:\servers.txt)
$Servers = $Servers | ? {$_} | select-object -uniqe |ForEach-Object {$_.TrimEnd()}
$Servers|ForEach-Object {
$tempobj=New-Object -TypeName PSObject
$tempobj | Add-Member -type NoteProperty -name Name -value $_
$tempobj | Add-Member -type NoteProperty -name isOnline -value $FALSE
$tempobj | Add-Member -type NoteProperty -name Installed -value $FALSE
$tempobj | Add-Member -type NoteProperty -name serviceRunning -value $FALSE
            [void]$Computers.Add($tempobj)

then You could work on array (no need for additional files)

$Computers|Where-Object {$_.isOnline -eq $TRUE}

etc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM