Delete OST file and run outlook process - forms

I have a form that im using to delete a ost file in powershell then starts outlook. I think the process to start outlook is opening quicker than the ost can be deleted. Here's what i have.
taskkill.exe /im outlook.exe /f
$OstPath = $Env:LocalAppData + "\Microsoft" + "\Outlook"
$ost = get-ChildItem $OstPath | where { $_.Extension -eq ".ost"}
$ost | remove-Item
Wait-Job $ost
Start-Process -FilePath "C:\Program Files\Microsoft Office 15\root\office15\outlook.exe"

This is the function i came up with and works really well with Office 2013 and Office 2016:
Function RebuildEmail
{
#COMMENT: Stops all Outlook process' and deletes .ost file then prompts to run setup.
$a = new-object -comobject wscript.shell
$intAnswer = $a.popup("This will stop Outlook and Skype for Business,`nRemoves the local copy of your email and will resynchronize from the exchange server. Be sure you have a steady internet connection! . `nDO YOU WANT TO CONTINUE?", `
0,"Service Desk",4)
If ($intAnswer -ne 6) {
$a.popup("Please call the Service Desk for support.")
} else {
$a.popup("Rebuilding will begin...")
Stop-Process -Name ("Outlook", "Lync")
$n = 0
Do
{
If(Get-Process -Name ("outlook", "Lync") -ErrorAction silentlycontinue)
{
Stop-Process -Name ("Outlook", "Lync") -ErrorAction SilentlyContinue
If ($n -lt 5)
{
$ExitLoop = $false
$n++
Start-Sleep -Seconds 3
If($n -eq 5){$ExitLoop = $true}
}
}
else {$ExitLoop = $true}
}
While ($ExitLoop -eq $false)
if ($n -ne 5)
{
$OstPath = $Env:LocalAppData + "\Microsoft" + "\Outlook"
$OSTs = Get-ChildItem $OstPath | where { $_.Extension -eq ".ost"}
$OSTs | Remove-Item
Start-Sleep -s 3
foreach ($ost in $OSTs)
{
$FilePath = $OstPath + "\" + $ost
$n = 0
Do
{
if(Test-Path $FilePath)
{
Remove-Item $FilePath
Start-Sleep -Seconds 5
$ExitLoop = $false
$n++
if($n -eq 5){$ExitLoop = $true}
}
else {$ExitLoop = $true}
}
While ($ExitLoop -eq $false)
if($n -ne 5)
{
$a = new-object -comobject wscript.shell
$intAnswer = $a.popup("The local copy of your email was successfully removed.", `
0,"Service Desk",0)
}
else
{
$a = new-object -comobject wscript.shell
$intAnswer = $a.popup("Unfortunatley, your local copy couldn't be removed. Please call the Service Desk.", `
0,"Service Desk",0)
}
}
}
else
{
$a = new-object -comobject wscript.shell
$intAnswer = $a.popup("Outlook was unable to close. Please call the Service Desk.", `
0,"Service Desk",0)
}
Start-Process -FilePath "C:\Program Files\Microsoft Office 15\root\office15\outlook.exe" -ErrorAction SilentlyContinue
Start-Process -FilePath "C:\Program Files (x86)\Microsoft Office\root\Office16\outlook.exe" -ErrorAction SilentlyContinue
Start-Process -FilePath "C:\Program Files\Microsoft Office 15\root\office15\lync.exe" -ErrorAction SilentlyContinue
Start-Process -FilePath "C:\Program Files (x86)\Microsoft Office\root\Office16\lync.exe" -ErrorAction SilentlyContinue
Start-Sleep -s 30
$a = new-object -comobject wscript.shell
$intAnswer = $a.popup("Please allow a few minutes to update folders. Call the Service Desk if issue persist.", `
0,"Service Desk",0)
}
}

Related

Powershell workflows, installing software locally after disabling UAC?

So I'm bored and trying to learn about WorkFlows in Powershell but somethings just not clicking. So I've got a script that prompts for admin creds to open a new POSH window, then makes the registry changes to disable UAC (only for the duration of the script), then called some exe and MSI installers located on a mapped drive.
import-module ActiveDirectory
$erroractionpreference = 'SilentlyContinue'
#Elevate running of script to Administrative
param([switch]$Elevated)
function Check-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
if ((Check-Admin) -eq $false) {
if ($elevated)
{
# could not elevate, quit
}
else {
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
}
exit
}
#Workflow to restart the pc
Workflow reboot_and_continue {
#The following section allows for changing the UAC settings for the duration of the script
{
New-Variable -Name Key
New-Variable -Name PromptOnSecureDesktop_Name
New-Variable -Name ConsentPromptBehaviorAdmin_Name
Function Set-RegistryValue($key, $name, $value, $type="Dword") {
If ((Test-Path -Path $key) -Eq $false) { New-Item -ItemType Directory -Path $key | Out-Null }
Set-ItemProperty -Path $key -Name $name -Value $value -Type $type
}
Function Get-RegistryValue($key, $value) {
(Get-ItemProperty $key $value).$value
}
$Key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$ConsentPromptBehaviorAdmin_Name = "ConsentPromptBehaviorAdmin"
$PromptOnSecureDesktop_Name = "PromptOnSecureDesktop"
Function Get-UACLevel(){
$ConsentPromptBehaviorAdmin_Value = Get-RegistryValue $Key $ConsentPromptBehaviorAdmin_Name
$PromptOnSecureDesktop_Value = Get-RegistryValue $Key $PromptOnSecureDesktop_Name
If($ConsentPromptBehaviorAdmin_Value -Eq 0 -And $PromptOnSecureDesktop_Value -Eq 0){
"Never notIfy"
}
ElseIf($ConsentPromptBehaviorAdmin_Value -Eq 5 -And $PromptOnSecureDesktop_Value -Eq 0){
"NotIfy me only when apps try to make changes to my computer(do not dim my desktop)"
}
ElseIf($ConsentPromptBehaviorAdmin_Value -Eq 5 -And $PromptOnSecureDesktop_Value -Eq 1){
"NotIfy me only when apps try to make changes to my computer(default)"
}
ElseIf($ConsentPromptBehaviorAdmin_Value -Eq 2 -And $PromptOnSecureDesktop_Value -Eq 1){
"Always notIfy"
}
Else{
"Unknown"
}
}
Function Set-UACLevel() {
Param([int]$Level= 2)
New-Variable -Name PromptOnSecureDesktop_Value
New-Variable -Name ConsentPromptBehaviorAdmin_Value
If($Level -In 0, 1, 2, 3) {
$ConsentPromptBehaviorAdmin_Value = 5
$PromptOnSecureDesktop_Value = 1
Switch ($Level)
{
0 {
$ConsentPromptBehaviorAdmin_Value = 0
$PromptOnSecureDesktop_Value = 0
}
1 {
$ConsentPromptBehaviorAdmin_Value = 5
$PromptOnSecureDesktop_Value = 0
}
2 {
$ConsentPromptBehaviorAdmin_Value = 5
$PromptOnSecureDesktop_Value = 1
}
3 {
$ConsentPromptBehaviorAdmin_Value = 2
$PromptOnSecureDesktop_Value = 1
}
}
Set-RegistryValue -Key $Key -Name $ConsentPromptBehaviorAdmin_Name -Value $ConsentPromptBehaviorAdmin_Value
Set-RegistryValue -Key $Key -Name $PromptOnSecureDesktop_Name -Value $PromptOnSecureDesktop_Value
Get-UACLevel
}
Else{
"No supported level"
}
}
Export-ModuleMember -Function Get-UACLevel
Export-ModuleMember -Function Set-UACLevel
}
set-uaclevel 0
#This section calls the installers from a network share and runs them locally
Invoke-Command -ComputerName $env:COMPUTERNAME -ScriptBlock { Start-Process -FilePath "g:\IT\software\ChromeSetup.exe" -ArgumentList "/s" -Wait }
if ($setup.exitcode -eq 0)
Invoke-Command -ComputerName $env:COMPUTERNAME -ScriptBlock { Start-Process -FilePath "g:\IT\support\NSG_Vipre_agent_ssi-mi.msi" -ArgumentList "-silent" -Wait }
if ($setup.exitcode -eq 0)
Invoke-Command -ComputerName $env:COMPUTERNAME -ScriptBlock { Start-Process -FilePath "G:\IT\software\spiceworks\install_collection.bat" -Wait }
if ($setup.exitcode -eq 0)
Line 25 is where I'm thinking of trying to introduce the work flow.. but on second thought it might be better to encompass the entire thing in the workflow... I just don't know.
I've tried searching but I just can't find any examples of how to install software using a workflow. the idea is to run a powershell window with admin creds, disabled UAC then reboot. Once started back up call the various installers then re-enable UAC and reboot again.
Thanks!

sharepoint powershell - Exception calling "ExecuteQuery" with "0" argument(s): "The underlying connection was closed:"

something is wrong and i don't know what's it ,the same script is working in my local machine but when i tried it in VM it just will not work and throw me exception
-the PowerShell is the same version
-the same PowerShell SDK
-i added rule to allowing PowerShell
-my user is admin
-all the parameters are correct and i can enter the SharePoint in browser
Import-Module 'C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll'
Import-Module 'C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll'
Clear-Host
# getting all argument before starting the process #
$SiteURL = "user"
$ListName = "list"
$Username ="email"
$Password ="pass"
if ($SiteURL -eq $null -or $ListName -eq $null -or $Username -eq $null -or $Password -eq $null)
{
Write-Output "Somthing went wrong!"
Write-Output "Some of the variables are not correct"
}
else
{
$outfile = $PSCommandPath | Split-Path -Parent
$outfile += '\items.txt'
Clear-Host
Write-Output "Getting Items"
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$securePassword=ConvertTo-SecureString $Password -AsPlainText -Force
$Context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $securePassword)
$Web = $Context.Web
$List = $Web.get_lists().getByTitle($ListName)
$itemCreateInfo = New-Object Microsoft.SharePoint.Client.ListItemCreationInformation
$ListItems = $List.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
$Context.Load($ListItems)
$Context.ExecuteQuery()
$ListItems | ForEach-Object {
$output=$_["Title"] + "~~"
$output | Out-File -FilePath $outfile -Append
}
Write-Output "Done!"
}
it's seems the security for the local machine has a SSL Certificate for my account by default but in the VM it was missing that Certificate, so i just invoked by using TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
to the first line of my power-shell code and everything worked nice
Works fine based on my testing.
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Clear-Host
# getting all argument before starting the process #
$SiteURL = "https://xxx.sharepoint.com/sites/lee"
$ListName = "testlist"
$Username ="user#xxx.onmicrosoft.com"
$Password ="password"
if ($SiteURL -eq $null -or $ListName -eq $null -or $Username -eq $null -or $Password -eq $null)
{
Write-Output "Somthing went wrong!"
Write-Output "Some of the variables are not correct"
}
else
{
$outfile = $PSCommandPath | Split-Path -Parent
$outfile += '\items.txt'
Clear-Host
Write-Output "Getting Items"
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$securePassword=ConvertTo-SecureString $Password -AsPlainText -Force
$Context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $securePassword)
$Web = $Context.Web
$List = $Web.get_lists().getByTitle($ListName)
$itemCreateInfo = New-Object Microsoft.SharePoint.Client.ListItemCreationInformation
$ListItems = $List.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
$Context.Load($ListItems)
$Context.ExecuteQuery()
$ListItems | ForEach-Object {
$output=$_["Title"] + "~~"
$output | Out-File -FilePath $outfile -Append
}
Write-Output "Done!"
}
Yes I confirm, it works, I had the same problem on a Windows 2012 R2 server

Powershell script to install software

I am trying to make a powershell script that I can use with an RMM tool. So, basically this powershell script would be executed on the local machine. It would need to check to see if the version of the application is installed and at least version number xx. If not installed, or version is less, it would then download executable and silently install it.
I found an example online for Adobe Reader that does work, but it doesn't do the check before hand. So, this script would install Adobe Reader every time it is ran.
$tempFolder=$Env:TEMP
function runProcess ($cmd, $params) {
$p = new-object System.Diagnostics.Process
$p.StartInfo = new-object System.Diagnostics.ProcessStartInfo
$exitcode = $false
$p.StartInfo.FileName = $cmd
$p.StartInfo.Arguments = $params
$p.StartInfo.UseShellExecute = $False
$p.StartInfo.RedirectStandardError = $True
$p.StartInfo.RedirectStandardOutput = $True
$p.StartInfo.WindowStyle = 1;
$null = $p.Start()
$p.WaitForExit()
$output = $p.StandardOutput.ReadToEnd()
$exitcode = $p.ExitCode
$p.Dispose()
$exitcode
$output
}
#download installer
invoke-webrequest "ftp://ftp.adobe.com/pub/adobe/reader/win/AcrobatDC/1500720033/AcroRdrDC1500720033_en_US.msi" -OutFile "$tempFolder\AcroRdrDC1500720033_en_US.msi" -ErrorAction Stop
#run installer
$res = runProcess msiexec "/i $tempFolder\AcroRdrDC1500720033_en_US.msi /qb"
#check if return code is 0
if(0 -ne $res[0]){
return "Failed to install Adobe Reader: $($res[0]) $($res[1])"
}
#download the patch
invoke-webrequest "ftp://ftp.adobe.com/pub/adobe/reader/win/AcrobatDC/1502320070/AcroRdrDCUpd1502320070.msp" -OutFile "$tempFolder\AcroRdrDCUpd1502320070.msp" -ErrorAction Stop
#install it
$res = runProcess msiexec "/p $tempFolder\AcroRdrDCUpd1502320070.msp /qb"
#check if return code is 0
if(0 -ne $res[0]){
return "Failed to install Adobe Reader DC Patch: $($res[0]) $($res[1])"
}else{
#Attempt to silently disable the auto updater if set in this script
new-itemproperty "HKLM:\Software\Policies\Adobe\Acrobat Reader\DC\FeatureLockDown" -name bUpdater -value 0 -ErrorAction SilentlyContinue
}
I think there are some things that may not be needed in this script. It also doesn't have the check for version.
Found this on another site, but not sure how to implement it. Also, it doesn't look like it checks for version number.
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;
return $x86 -or $x64;
}
Ideally, I would like to set the parameters at the top so I could use a template for other executables. For instance
$app_name
$app_version
$app_url
$app_filename
$app_executable
$app_arguments
Any help would be greatly appreciated.
I did some more digging and found this post: How to check if a program is installed and install it if it is not?
Which allows for matching Name and Version:
$tempdir = Get-Location
$tempdir = $tempdir.tostring()
$appName = '*AirParrot*'
$appVersion = "2.6.8"
$msiFile = $tempdir+"\microsoft.interopformsredist.msi"
$msiArgs = "-qb"
function Get-InstalledApps
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = #(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and $_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate, DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $appName -and $_.DisplayVersion -ge $appVersion}
If ($result -eq $null) {
(Start-Process -FilePath $msiFile -ArgumentList $msiArgs -Wait -Passthru).ExitCode
}

How can I catch Browsererrors like 504 in a SharePoint2013 Warm-Up Skript?

I am a freshman at PowerShell and I try to implement a SharePoint Warm-Up Skript.
This Skript is not originally mine, i only edited a existing one. Now it run nicely. But if a error occured like a DNS look up fail i want a Output in my Logfile like: "A DNS look up fail occured at URL..."
I want to catch the Browsererrors 400, 404 and 504. How can I catch them?
Here my code so far:
Function WarmUp() {
# Get URL list
Add-PSSnapIn Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$was = Get-SPWebApplication -IncludeCentralAdministration
$was |? {$_.IsAdministrationWebApplication -eq $true} |% {$caTitle = Get-SPWeb $_.Url | Select Title}
# Warm up SharePoint web applications
Write-Host "Opening Web Applications..."
$global:ie = New-Object -Com "InternetExplorer.Application"
$global:ie.Navigate("about:blank")
$global:ie.Visible = $true
$global:ieproc = (Get-Process -Name iexplore)|? {$_.MainWindowHandle -eq $global:ie.HWND}
#Navigate here to all Applications, Collections and sites
# Close IE window
if ($global:ie) {
Write-Host "Closing IE"
$global:ie | Stop-Process -Force -ErrorAction SilentlyContinue
}
$global:ieproc | Stop-Process -Force -ErrorAction SilentlyContinue
# Clean Temporary Files
Remove-item "$env:systemroot\system32\config\systemprofile\appdata\local\microsoft\Windows\temporary internet files\content.ie5\*.*" -Recurse -ErrorAction SilentlyContinue
Remove-item "$env:systemroot\syswow64\config\systemprofile\appdata\local\microsoft\Windows\temporary internet files\content.ie5\*.*" -Recurse -ErrorAction SilentlyContinue
}
Function IENavigateTo([string] $url, [int] $delayTime = 500) {
# Navigate to a given URL
if ($url) {
if ($url.ToUpper().StartsWith("HTTP")) {
Write-Host " Navigating to $url"
try {
$global:ie.Navigate($url)
#If the certificate is invalid, bypass the error to show the context.
if ($global:ie.document.url -Match "invalidcert")
{
"Bypassing SSL Certificate Error Page";
$sslbypass=$global:ie.Document.getElementsByTagName("a") | where-object {$_.id -eq "overridelink"};
$sslbypass.click();
"Sleep for 5 seconds while final page loads";
start-sleep -s 5;
}
} catch {
try {
$pid = $global:ieproc.id
} catch {}
Write-Host " IE not responding. Closing process ID $pid"
$global:ie | Stop-Process -Force -ErrorAction SilentlyContinue
$global:ieproc | Stop-Process -Force -ErrorAction SilentlyContinue
$global:ie = New-Object -Com "InternetExplorer.Application"
$global:ie.Navigate("about:blank")
$global:ie.Visible = $true
$global:ieproc = (Get-Process -Name iexplore)|? {$_.MainWindowHandle -eq $global:ie.HWND}
}
IEWaitForPage $delayTime
}
}
}
Function IEWaitForPage([int] $delayTime = 500) {
# Wait for current page to finish loading
$loaded = $false
$loop = 0
$maxLoop = 20
while ($loaded -eq $false) {
$loop++
# Wait until the page is loaded.
While ($global:ie.ReadyState -ne 4) {
Start-Sleep -Seconds 2
Write-Host "Busy!"
}
if ($loop -gt $maxLoop) {
$loaded = $true
}
[System.Threading.Thread]::Sleep($delayTime)
# If the browser is not busy, the page is loaded
if (-not $global:ie.Busy)
{
$loaded = $true
}
}
}
#Main
if(-not(Test-Path "C:\Logs\SharePoint\WarmUpLogTest")){New-Item -ItemType Directory -Path "C:\Logs\SharePoint\WarmUpLogTest"}
Start-Transcript -Path ("C:\Logs\SharePoint\WarmUpLogTest\SPWarmUp{0:yyyy-MM-dd}.txt" -f $(get-date)) -Append
WarmUp
Stop-Transcript
If you run powershell V3 or newest you can add this on top of your IENavigateTo
try{invoke-webrequest $url}
catch{$_.errordetails|select -expand message}
without V3 you can try something like
$request = [System.Net.WebRequest]::Create($url)
try{$response = $request.GetResponse() }catch{$_.exception.message}

Powershell script to run on all computers in domain - wait until computer is online

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.