Сценарий Powershell для вывода списка запланированных задач в удаленных системах

Я хочу написать сценарий PowerShell, который перечисляет все запланированные задачи в удаленных системах и включает учетную запись пользователя, которая будет использоваться для выполнения каждой задачи.

локальная система работает под управлением Windows 7 с PowerShell 3.0. Удаленные системы варьируются от Server 2003 до 2008 R2 с версиями PowerShell от 2.0 до 3.0.

какие команды или функции PowerShell можно использовать для этой задачи?

2
задан Iszi
03.01.2023 18:11 Количество просмотров материала 3335
Распечатать страницу

4 ответа

Я, наконец, написал сценарий, который соответствует моим потребностям. Этот сценарий будет "сканировать" все серверы, перечисленные в объявлении, поиск в c:\Windows\System32\tasks папка для xml-файлов. Затем он запишет значение XML-узла UserID каждого файла в окончательный CSV-файл.

еще не идеально, но полностью работает, чтобы перечислить все задачи всех серверов, и войти, какая учетная запись пользователя используется для их запуска.

<#
.Synopsis
   PowerShell script to list all Scheduled Tasks and the User ID
.DESCRIPTION
   This script scan the content of the c:\Windows\System32\tasks and search the UserID XML value. 
   The output of the script is a comma-separated log file containing the Computername, Task name, UserID.
#>

Import-Module ActiveDirectory
$VerbosePreference = "continue"
$list = (Get-ADComputer -LDAPFilter "(&(objectcategory=computer)(OperatingSystem=*server*))").Name
Write-Verbose  -Message "Trying to query $($list.count) servers found in AD"
$logfilepath = "$home\Desktop\TasksLog.csv"
$ErrorActionPreference = "SilentlyContinue"

foreach ($computername in $list)
{
    $path = "\" + $computername + "\c$\Windows\System32\Tasks"
    $tasks = Get-ChildItem -Path $path -File

    if ($tasks)
    {
        Write-Verbose -Message "I found $($tasks.count) tasks for $computername"
    }

    foreach ($item in $tasks)
    {
        $AbsolutePath = $path + "\" + $item.Name
        $task = [xml] (Get-Content $AbsolutePath)
        [STRING]$check = $task.Task.Principals.Principal.UserId

        if ($task.Task.Principals.Principal.UserId)
        {
          Write-Verbose -Message "Writing the log file with values for $computername"           
          Add-content -path $logfilepath -Value "$computername,$item,$check"
        }

    }
}

на выходе получаем CSV-файл создается на рабочем столе, как это one:

> SRV028,CCleanerSkipUAC,administrator
> SRV029,GoogleUpdateTaskMachineCore,System
> SRV030,GoogleUpdateTaskMachineUA,System
> SRV021,BackupMailboxes,DOMAIN\administrator
> SRV021,Compress&Archive,DOMAIN\sysScheduler
8
отвечен Ob1lan 2023-01-05 01:59

Эй думал, что поделюсь модифицированной версией скрипта, опубликованного Ob1lan. Изменение помогает найти задачи во вложенных папках и перечисляет состояние задачи, а также сведения, включенные в оригинал.

$Computers = (get-adcomputer -filter {operatingsystem -like "*server*"}).name
$ErrorActionPreference = "SilentlyContinue"
$Report = @()
foreach ($Computer in $Computers)
{
    if (test-connection $Computer -quiet -count 1)
    {
        #Computer is online
        $path = "\" + $Computer + "\c$\Windows\System32\Tasks"
        $tasks = Get-ChildItem -recurse -Path $path -File
        foreach ($task in $tasks)
        {
            $Details = "" | select ComputerName, Task, User, Enabled, Application
            $AbsolutePath = $task.directory.fullname + "\" + $task.Name
            $TaskInfo = [xml](Get-Content $AbsolutePath)
            $Details.ComputerName = $Computer
            $Details.Task = $task.name
            $Details.User = $TaskInfo.task.principals.principal.userid
            $Details.Enabled = $TaskInfo.task.settings.enabled
            $Details.Application = $TaskInfo.task.actions.exec.command
            $Details
            $Report += $Details
        }
    }
    else
    {
        #Computer is offline
    }
}
$Report | ft

Примечание: если у вас много серверов, это займет много времени. Если вы хотите запустить его параллельно, вы можете использовать скрипт invoke-parallel (Google it), который является значительно быстрее:

. \server\path\to\invoke-parallel.ps1
$Computers = (get-adcomputer -filter {operatingsystem -like "*server*"}).name
$ErrorActionPreference = "SilentlyContinue"
$Scriptblock =
{
    $path = "\" + $_ + "\c$\Windows\System32\Tasks"
    $tasks = Get-ChildItem -recurse -Path $path -File
    foreach ($task in $tasks)
    {
        $Details = "" | select ComputerName, Task, User, Enabled, Application
        $AbsolutePath = $task.directory.fullname + "\" + $task.Name
        $TaskInfo = [xml](Get-Content $AbsolutePath)
        $Details.ComputerName = $_
        $Details.Task = $task.name
        $Details.User = $TaskInfo.task.principals.principal.userid
        $Details.Enabled = $TaskInfo.task.settings.enabled
        $Details.Application = $TaskInfo.task.actions.exec.command
        $Details
    }
}
$Report = invoke-parallel -input $Computers -scriptblock $Scriptblock -throttle 400 -runspacetimeout 30 -nocloseontimeout
$Report | ft 

пример вывода:

Screenshot

5
отвечен laoist 2023-01-05 04:16

я использовал эту команду для получения списка всех задач:

        Invoke-Command -ComputerName "computername" -Credential Get-Credential {schtasks.exe}
2
отвечен sanyam jain 2023-01-05 06:33

Watch out: предостережение: лучше использовать-literalpath, например:

$TaskInfo = [xml](Get-Content -literalpath $AbsolutePath)

или get-content ничего не вернет, если ваши имена задач или фолдеры содержат подстановочные знаки или символы регулярных выражений, как в моем случае "[' и "]"...

да, Powershell интерпретирует не только строки литералов, но и содержимое переменных типа string.

-1
отвечен Patrick E 2023-01-05 08:50

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх