रिमोट सिस्टम पर अनुसूचित कार्यों को सूचीबद्ध करने के लिए पॉवर्सशेल स्क्रिप्ट


9

मैं एक PowerShell स्क्रिप्ट लिखना चाहता हूं जो दूरस्थ सिस्टम पर सभी शेड्यूल किए गए टास्क को सूचीबद्ध करती है, और उस उपयोगकर्ता खाते को भी शामिल करती है जिसका उपयोग प्रत्येक कार्य को चलाने के लिए किया जाएगा।

स्थानीय सिस्टम विंडोज 7 चला रहा है, जिसमें पावरशेल 3.0 है। दूरस्थ सिस्टम सर्वर 2003 से 2008 R2 तक, PowerShell संस्करणों के साथ 2.0 से 3.0 तक है।

PowerShell कमांड या फ़ंक्शंस मैं इस कार्य के लिए क्या उपयोग कर सकता हूं?


स्थानीय प्रणाली क्या उपयोग कर रही है? (OS & PowerShell संस्करण)
Iszi

@root: जैसा कि इज़ी ने कहा, यह Cmdlet विंडोज सर्वर 2012 या विंडोज 8 पर समर्थित है। कृपया टिप्पणी / जवाब देने से पहले सवाल को ध्यान से पढ़ें।
Ob1lan

1
@ आईज़ी स्थानीय प्रणाली
पावरशेल

@ Ob1lan मैंने
जड़

@ यदि आप Win7 SP1 चला रहे हैं, तो आप PowerShell 4.0 में अपग्रेड करने पर विचार कर सकते हैं। यह आपके विकल्पों को थोड़ा विस्तारित करने में मदद कर सकता है, हालांकि यह अभी भी आपको विन 8.1 सिस्टम के स्तर तक नहीं लाएगा। मैं यह भी 100% सुनिश्चित नहीं हूं कि जब स्थानीय सिस्टम का संस्करण रिमोट सिस्टम पर एक से अलग है तो पावरशेल कैसे काम करता है। मैंने यहाँ उसके लिए एक प्रश्न पोस्ट किया है
इस्जी

जवाबों:


8

मैंने आखिरकार एक स्क्रिप्ट लिखी जो मेरी ज़रूरतों के अनुरूप है। यह स्क्रिप्ट AD में सूचीबद्ध सभी सर्वरों को xml फ़ाइलों के लिए c: \ Windows \ System32 \ टास्क फोल्डर में 'स्कैन' करेगी। फिर यह प्रत्येक फाइल के UserID xml नोड का मूल्य लिखेगा, अंतिम 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"
        }

    }
}

आउटपुट आपके डेस्कटॉप पर उत्पन्न एक अल्पविराम से अलग की गई फ़ाइल है, जैसे यह:

> SRV028,CCleanerSkipUAC,administrator
> SRV029,GoogleUpdateTaskMachineCore,System
> SRV030,GoogleUpdateTaskMachineUA,System
> SRV021,BackupMailboxes,DOMAIN\administrator
> SRV021,Compress&Archive,DOMAIN\sysScheduler

यहां बिना पढ़े XML का PS वर्जन: stackoverflow.com/a/53123962/1747983
Tilo

नोट: पैट्रिक ई ने एक टिप्पणी पोस्ट की है (एक उत्तर के रूप में: superuser.com/a/1368312/19792 ), -LiteralPathजिसे Get-Contentकमांड में उपयोग करने का सुझाव दिया गया है । मैं हालांकि इसकी वैधता पर टिप्पणी नहीं कर सकता।
mwfearnley

6

हे सोचा कि मैं 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

नोट : यदि आपके पास कई सर्वर हैं, तो इसे चलाने में लंबा समय लगेगा। यदि आप इसे समानांतर में चलाना चाहते हैं, तो आप इनवोक-पैरेलल स्क्रिप्ट (इसे Google) का उपयोग कर सकते हैं, जो कि काफी तेज है:

. \\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 

उदाहरण आउटपुट :

स्क्रीनशॉट


2

मैंने सभी कार्यों को सूचीबद्ध करने के लिए इस कमांड का उपयोग किया:

        Invoke-Command -ComputerName "computername" -Credential Get-Credential {schtasks.exe}

1
धन्यवाद, लेकिन मैं पहले से ही इस आदेश को जानता हूं। समस्या यह है कि PowerShell रीमोटिंग को हमारी सुरक्षा नीति के कारण नेटवर्क के सभी कंप्यूटरों पर प्रदर्शित नहीं किया जा सकता है। मैं एक और स्क्रिप्ट रास्ते पर हूँ और अधिक सरल।
Ob1lan

1

बाहर देखो: चेतावनी: बेहतर उपयोग -लिटरलपथ, जैसे:

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

या get-contentअगर आपके कार्यनाम या फ़ोल्डरनाम में कोई वाइल्डकार्ड या रेगेक्स वर्ण शामिल हैं तो कुछ भी नहीं होगा, जैसे मेरे मामले में "['और"] "...

हां, पॉवर्सल न केवल शाब्दिक तार की व्याख्या करता है, बल्कि स्ट्रिंग प्रकार की सामग्री भी है।


मैं यह मान रहा था कि इसे उतारा गया था क्योंकि यह उपरोक्त उत्तर (ओं) पर एक टिप्पणी होनी चाहिए जो सिर्फ उपयोग करते हैं Get-Content $AbsolutePath? मैं पॉवरशेल के साथ अच्छा नहीं हूं, लेकिन मैं आपके लिए डाउनवोट को रद्द करना चाहूंगा, अगर आप उपरोक्त के लिए कोई उद्धरण दे सकते हैं।
mwfearnley
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.