Save file on localy managementserver

I’m trying to create a script that checks the task scheduler and saves the result in an Excel file on the server from which the script is run, but it’s not working. Instead, it keeps trying to save the file on the server being checked.

$option = New-PSSessionOption -IncludePortInSPN
$pssession = New-PSSession -ComputerName server18359, server18357, server18236 -SessionOption $option

$excel1 = New-ConditionalText -Range "A1:M1" -BackgroundColor lightBlue -ConditionalTextColor Black

$folderName = "antura"

Invoke-Command -Session $pssession -ScriptBlock {
$tasks = Get-ScheduledTask | Where-Object { $_.TaskPath -like "*\$folderName\*" -and $_.State -eq "Ready" }

if ($tasks.Count -ne 0) {
    Write-Host "Inga scheduled tasks hittades i mappen $folderName."
} else {
    $taskInfo = $tasks | Get-ScheduledTaskInfo | Select-Object TaskName, TaskPath, LastRunTime, NextRunTime
    $outputPath = "C:\pstemp\tasks.xlsx"
    $taskInfo | Export-Excel -Path $outputPath `
        -AutoSize `
        -ConditionalText $excel1 `
        -WorksheetName "PowerShell Scripts" `
        -BoldTopRow `
        -FreezeTopRow `
        -AutoFilter
}
}

Hey there skoeId!

It looks like that’s occurring because you’re Export-Excel process is happening inside of your invoke-command. Anything inside that script block is going to occur on the remote system. Think of it like there’s a powershell session running on that other system and all the work is occurring there, and you just have a remote connection so you can see it happening locally.

You need to run the export-excel function inside of the local session, not the remote session (outside of the script block of the invoke-command).

Furthermore, the variables that you are defining locally on the server that runs it, likely aren’t being utilized how they are being referenced because it’s a local variable and the remote session is not aware of that variable on the remote computer. Variables like $foldername and $excel1 are the variables i’m talking about. They are defined locally in the current session, not in the remote session. Look into the using scope modifier: about Scopes - PowerShell | Microsoft Learn and Invoke-Command (Microsoft.PowerShell.Core) - PowerShell | Microsoft Learn

Instead in order to get the tasks to deal with locally, you probably want to do is something more like:

$tasks = Invoke-Command -Session $pssession -ScriptBlock {
Get-ScheduledTask | Where-Object { $_.TaskPath -like "*\$using:folderName\*" -and $_.State -eq "Ready" }

Note it’s possible that you may want to also to do the get-scheduledtaskinfo remotely too, I’m not sure (writing this without testing it). Ultimately though you need the data you are working with to be saved in the local system, not the remote system.

Lastly, I’d avoid using the backtics. They are generally not a great thing to use. To make the code more readable and not as long left to right, you actually should be able to completely remove those and instead use splatting: about Splatting - PowerShell | Microsoft Learn

1 Like

I will take a look at this and try to make it as I want.
Thanks.

Works after some changes.


$computers  = Import-Csv "C:\Scripts\Servers\allServers.txt", "C:\Scripts\Servers\allServersTest.txt", "C:\Scripts\Servers\allServersEdu.txt"
$excel1     = New-ConditionalText -Range "A1:M1" -BackgroundColor lightBlue -ConditionalTextColor Black
$outputPath = "C:\pstemp\tasks.xlsx"


$option    = New-PSSessionOption -IncludePortInSPN
$pssession = New-PSSession -ComputerName $computers.Name -SessionOption $option

$tasks = Invoke-Command -Session $pssession{
if ($tasks -ne 0) {
    Get-ScheduledTask |
        where {$_.TaskPath -like "*\test\*" -and $_.State -eq "Ready"}  |
        Get-ScheduledTaskInfo |
        Select-Object TaskName, TaskPath, LastRunTime, NextRunTime
}
}

$localTasks = Get-ScheduledTask |
        where {$_.TaskPath -like "*\test\*" -and $_.State -eq "Ready"}  |
        Get-ScheduledTaskInfo |
        Select-Object TaskName, TaskPath, LastRunTime, NextRunTime

$localTasks + $tasks | Export-Excel -Path $outputPath `
    -AutoSize `
    -ConditionalText $excel1 `
    -WorksheetName "PowerShell Scripts" `
    -BoldTopRow `
    -FreezeTopRow `
    -AutoFilter

Remove-PSSession $pssession

Just a small note - using backticks as line continuation characters is considered bad style and quite error prone.
The much better option would be to use splatting instead. :wink:

:love_you_gesture:t3:

I have made some changes after your note and I believe you mean something like this.

$computers  = Import-Csv "C:\Scripts\Servers\allServers.txt", "C:\Scripts\Servers\allServersTest.txt", "C:\Scripts\Servers\allServersEdu.txt"
$excel1     = New-ConditionalText -Range "A1:M1" -BackgroundColor lightBlue -ConditionalTextColor Black
$outputPath = "C:\pstemp\tasks.xlsx"

$option    = New-PSSessionOption -IncludePortInSPN
$pssession = New-PSSession -ComputerName $computers.Name -SessionOption $option

$tasks = Invoke-Command -Session $pssession {
    if ($tasks -ne 0) {
        Get-ScheduledTask |
            Where-Object { $_.TaskPath -like "*\test\*" -and $_.State -eq "Ready" } |
            Get-ScheduledTaskInfo |
            Select-Object TaskName, TaskPath, LastRunTime, NextRunTime
    }
}

$localTasks = Get-ScheduledTask |
    Where-Object { $_.TaskPath -like "*\test\*" -and $_.State -eq "Ready" } |
    Get-ScheduledTaskInfo |
    Select-Object TaskName, TaskPath, LastRunTime, NextRunTime

$excelParams = @{
    Path            = $outputPath
    AutoSize        = $true
    ConditionalText = $excel1
    WorksheetName   = "PowerShell Scripts"
    BoldTopRow      = $true
    FreezeTopRow    = $true
    AutoFilter      = $true
}

$localTasks + $tasks | Export-Excel @excelParams

Remove-PSSession $pssession