Вопрос

I have pieced together the following PowerShell script that deletes a file from the public desktop of every machine in an OU on our domain, and then copies a replacement file back to replace it. It works well, except for the machines that are offline. What would be the best way to have the script run on a machine once it comes online? My best guess is to have it put any offline machine in a list, then re-run a few hours later for the computers on that list. Is there a better way?

$DESTINATION = "c$\Users\Public\Desktop"
$REMOVE = "ComputerName"
$strFilter = "computer"

$objDomain = New-Object System.DirectoryServices.DirectoryEntry

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = "LDAP://OU=MyOU,DC=Domain,DC=com"
$objSearcher.SearchScope = "Subtree" 
$objSearcher.PageSize = 1000 

$objSearcher.Filter = "(objectCategory=$strFilter)"
$colResults = $objSearcher.FindAll()

foreach ($i in $colResults) 
    {
        $objComputer = $i.GetDirectoryEntry()
        $REMOVE = $objComputer.Name
        #Ping system to see if it's on
        $rtn = Test-Connection -CN $REMOVE -Count 2 -BufferSize 16 -Quiet

        IF($rtn -match 'True') {

            Remove-Item "\\$REMOVE\$DESTINATION\SparksNET.url" -Recurse
            Copy-Item "\\spd3\PD IT stuff\Software\Desktop Icons\mySparks.website" "\\$REMOVE\$DESTINATION"   
        }
        ELSE { 
        }

    }
Это было полезно?

Решение

Everyone is 100% correct, you should do this through GPO. However, if you crazily want to do it through PowerShell, you could do it the way I have outlined below. I threw your code into it - so it might be a tad messy.

Start off by pulling in the list of PC's and then send them all off to a job...

if(Test-Path "c:\LogPath"){
}else {
mkdir "c:\LogPath"
}

$time=Get-Date -Format s
$date=Get-Date -Format F

"LOG FILE CREATED - $date" | Add-Content $log

$objDomain = New-Object System.DirectoryServices.DirectoryEntry

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = "LDAP://OU=MyOU,DC=Domain,DC=com"
$objSearcher.SearchScope = "Subtree" 
$objSearcher.PageSize = 1000 

$objSearcher.Filter = "(objectCategory=$strFilter)"
$colResults = $objSearcher.FindAll()

foreach($Obj in $colResults){ 

        $objComputer = $Obj.GetDirectoryEntry()
        $remotePC = $objComputer.Name


    #Imports all functions used in script
    . "C:\PathToYourJobScript.ps1"



    #Creating Jobs
    $jobs = (get-job -state running | Measure-Object).count 
        Get-job -State Completed | Remove-Job
            while($jobs -ge 5)    
               {
                  #get currently running jobs after restart

            get-job -state running | %{write-host $_.PSBeginTime} | ?{($_.PSBeginTime - $(Get-Date)).Minutes -gt 10} | Remove-Job
            Write-host "Currently running maximum threads at: $jobs `n Sleeping 5 seconds"  -ForegroundColor DarkYellow

            start-sleep -seconds 5

            $jobs = (get-job -state running | Measure-Object).count 
               }

    Write-host "`t`tCreating Thread for $remotePC" -ForegroundColor Yellow

    start-job $DeleteFile -ArgumentList $remotePC -Name $remotePC 
    Receive-Job $remotePC

    "$remotePC; Starting Job at; $time" | Add-Content $log
    }

In your actual job script PS1, wrap your code above into one function

$DeleteFile={Param(
     [Parameter(Mandatory=$true)]
    [string]$remotePC
    ) 
<#
.SYNOPSIS 

.DESCRIPTION 

.NOTES 


#>

##Globals
$DESTINATION = "c$\Users\Public\Desktop"
$REMOVE = "ComputerName"
$strFilter = "computer"

        #Ping system to see if it's on


        if(Test-Connection -ComputerName $remotePC -Count 2  -BufferSize 16 -ErrorAction SilentlyContinue){
            Remove-Item "\\$REMOVE\$DESTINATION\SparksNET.url" -Recurse
            Copy-Item "\\spd3\PD IT stuff\Software\Desktop Icons\mySparks.website" "\\$REMOVE\$DESTINATION" 
            "$remotePC; Removal Complete; $time" | Add-Content $log  
            }
            ELSE 
            { 
            do {Start-Sleep -Seconds 300;  "$remotePC; Ping Fail; $time" | Add-Content $log}
            until (Test-Connection -ComputerName $remotePC -Count 2  -BufferSize 16 -ErrorAction SilentlyContinue)
            Remove-Item "\\$REMOVE\$DESTINATION\SparksNET.url" -Recurse
            Copy-Item "\\spd3\PD IT stuff\Software\Desktop Icons\mySparks.website" "\\$REMOVE\$DESTINATION" 
            "$remotePC; Removal Complete; $time" | Add-Content $log  
            }
}

This will check every 5 minutes if the PC is online and wait until it gets a response to proceed. Once an item is tossed into a job, you loose site of its progress and would want to log accordingly so you know its position.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top