【问题标题】:Read csv file to create tasks that trigger from an event id using powershell and Task Scheduler COM-Object使用 powershell 和任务计划程序 COM-Object 读取 csv 文件以创建从事件 id 触发的任务
【发布时间】:2018-10-11 15:46:37
【问题描述】:

我创建了一个如下所示的 CSV 文件

sequence,reportsource,reportname,reportid,fullpath

它包含多行计划任务的配置数据。我已经想出使用 import-csv 来获取文件的内容。现在我想遍历文件的每一行并将该行的所有值存储到变量 - 集合($sequence,$reportsource,$reportname,$reportid,$fullpath),所以我可以使用这些值创建计划任务,但我不知道如何访问 import-csv 提供的对象。我需要 csv 中的这些值将参数传递给 schtasks.exe 以创建我的任务。

$path = "C:\Workspace\macros\FullReportPathMR.csv"
$PSVersionTable.PSVersion

$csv = Import-CSV -Path $path -Delimiter ";" | %{

##SCHTASKS /Create /TN $($_.reportname) /sc monthly /tr "C:\Program Files (x86)\Microsoft Office###\Office14\EXCEL.EXE"
#New-ScheduledTaskAction -Execute "C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE" -Argument #"$($_.fullpath)"
#}

# The name of the scheduled task
[string]$TaskName = "$($_.reportsource) - $($_.reportname) - $($_.reportid)"
# The description of the task
[string]$TaskDescr = "Hello, it's you again! I am $($_.reportname) and I will get started, when Report ID $($_.reportid) is fired. Have a nice day!"
# The Task Action command
$TaskCommand0 = "kill.cmd"
$TaskCommand1 = "`"C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE`""

# The Task Action command argument
$TaskArg = "hallelujah"
$TaskArg1 = "$($_.fullpath)"
# attach the Task Scheduler com object
$service = new-object -ComObject("Schedule.Service")
# connect to the local machine. 
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa381833(v=vs.85).aspx
$service.Connect()
$rootFolder = $service.GetFolder("\")

$TaskDefinition = $service.NewTask(0) 
$TaskDefinition.RegistrationInfo.Description = "$TaskDescr"
$TaskDefinition.Settings.Enabled = $true
$TaskDefinition.Settings.AllowDemandStart = $true

$triggers = $TaskDefinition.Triggers
#http://msdn.microsoft.com/en-us/library/windows/desktop/aa383915(v=vs.85).aspx
$trigger = $triggers.Create(0) # Creates an "On an event" trigger
$trigger.Subscription = "<QueryList><Query Id='0'><Select Path='Application'>*[System[Provider[@Name='$($_.reportsource)'] and EventID='$($_.reportid)']]</Select></Query></QueryList>"

# http://msdn.microsoft.com/en-us/library/windows/desktop/aa381841(v=vs.85).aspx
$Action = $TaskDefinition.Actions.Create(0)
$action.Path = "$TaskCommand0"
$action.Arguments = "$TaskArg"
$Action = $TaskDefinition.Actions.Create(0)
$action.Path = "$TaskCommand1"
$action.Arguments = "$TaskArg1"

#http://msdn.microsoft.com/en-us/library/windows/desktop/aa381365(v=vs.85).aspx
$rootFolder.RegisterTaskDefinition("$TaskName",$TaskDefinition,6,"System",$null,5)

Write-Host $($_.sequence) $($_.reportsource) $($_.reportname) $($_.reportid) $($_.fullpath) "task created successfully."

}

CSV 文件包含

sequence;reportsource;reportname;reportid;fullpath
1;Monthly Report;MR1;3;C:\Workspace\macros\1.txt
2;Monthly Report;MR2;6;C:\Workspace\macros\2.txt
3;Monthly Report;MR3;9;C:\Workspace\macros\3.txt
4;Monthly Report;MR4;12;C:\Workspace\macros\4.txt

https://www.verboon.info/2013/12/powershell-creating-scheduled-tasks-with-powershell-version-3/

https://community.spiceworks.com/topic/1028906-trigger-schedule-task-on-an-eventid

https://powershell.org/forums/topic/scheduled-task-with-multiple-actions/

整个过程在带有 PS 2.0.-1.-1 管理机器的 Windows 7 上运行,并使用所需的参数和参数创建了 4 个任务。订阅 - 事情有点棘手,因为我无法使用 GUI 操作事件触发器,只能编辑 XML。每个任务提供 2 个操作。

【问题讨论】:

  • 请显示一些代码。我们可以帮助您,但前提是我们有事可做。
  • 我现在无法访问我的代码,但这个问题一直在我脑海中旋转。我会尽快提供:)
  • 请将编辑内容发布到您的帖子中,而不是在 cmets 中。这是为了便于阅读和其他帮助。也请以太回复我的评论或标题帖子而不是此评论,因为它属于 Ortolar
  • 用你的工作代码更新了我的帖子
  • 非常好,谢谢

标签: powershell


【解决方案1】:

好吧,这个问题看起来很简单

“如何将 CSV 的值存储在变量中并循环遍历它们?”

让我们回顾一些基本的 Powershell 概念,以了解您应该寻找什么。

解决办法是。

Import-Csv -Path "C:\Test.csv" | %{
    Put Code Here
}

好的,让我们解释一下。

让我们有一个名为 test.csv 的 csv 文件,里面看起来像

"FirstName","LastName","Age" "Bill","Boxer","52" "Steve","Nix","21"

当我调用 Import-CSV 时,它会创建一个 PSObject,其属性等于标题(CSV 的第一行):

(Import-csv "C:\Test.csv").FirstName

会回来

Bill Steve

在 powershell 中,我们喜欢管道 | 它的作用是获取上一个命令的信息,并使用 $_ 作为变量将其移动到下一个命令。我们也喜欢称为 Alias 的速记。 就像%{ Code Here }foreach-object 的简写

所以

Import-csv "C:\Test.csv" | %{
    "My Name Is $($_.FirstName) $($_.LastName) and I am $($_.Age) years old"
}

将从 CSV 中获取数据并将其转换为 PSObject。然后它将 | 管道传输到 Foreach-Object aka %{} 然后显示字符串:

My Name Is Bill Boxer and I am 52 years old My Name Is Steve Nix and I am 21 years old

顺便说一句,引号内的 $() 称为表达式“$(Code here)” 允许您在字符串中输出代码

"Hello $_.FirstName"

将显示变量 $_ 中的所有内容,然后在其末尾添加一个 .FirstName,例如:

@{FirstName=Bill; LastName=Boxer; Age=52}.FirstName

但是当您添加 $() 表达式时,您是说将此部分作为代码运行。

"Hello $($_.FirstName)"

表演

Hello Bill

让我们看看您在 cmets 中发布的代码 (请记住编辑您的帖子并将其发布到那里以供其他人阅读。

根据我在上面发布的问题是您的 CSV 不是 CSV。 CSV 代表逗号分隔值。您的值用分号分隔。

您需要在 import-Csv -Delimiter ";" 的参数中定义它

一个工作脚本是这样的:

$path = "C:\Workspace\macros\FullReportPathMR.csv"
Import-CSV -Path $path -Delimiter ";" | %{
    "$($_.sequence) $($_.reportsource) $($_.reportname) $($_.reportid) $($_.fullpath)"
}

输出

1 Monthly Report MR1 3 C:\Workspace\macros\1.txt 2 Monthly Report MR2 6 C:\Workspace\macros\2.txt 3 Monthly Report MR3 9 C:\Workspace\macros\3.txt 4 Monthly Report MR4 12 C:\Workspace\macros\4.txt

【讨论】:

  • 见鬼,我第一次得到输出!!好的!我需要提供分隔符,好的。所以现在我可以将“变量”交给 schtasks。但是这个我会在星期一做
  • 请把我的答案标记为正确,或者点赞。谢谢
  • 感谢您非常详细的回答!!我已经投了赞成票。如果这件事发生了,我所期待的,我将标记为答案。谢谢!!
  • 好的,让我们考虑一下:有一个循环,每次迭代,都会使用 schtasks 创建另一个任务,其中 $($_.sequence) 和其他变量包含我需要的值。由于有 2 个循环,我如何确保将正确的值传递给它?我需要确保第一个循环的索引(包含计数变量 $i)引用 csv 的相应行?
  • 我认为您可能需要为此打开另一个问题。这是关于如何循环单个 CSV。我很乐意为您提供更多帮助,但我需要一个带有示例代码的新问题。但是,您知道这是 powershell,如果您阅读我的整篇文章,它会指出管道的使用和管道中的传递对象。 [i] 的想法在 foreach 对象中没有位置
【解决方案2】:

下面的代码将加载代码所在的 CSV。
然后它将在文件内部循环并创建计划任务。
此脚本需要管理员权限才能创建新的计划任务,它将以当前用户身份创建任务。

# get scripth path location
$scriptpath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition

# import CSV
$csvdata = Import-Csv "$scriptpath\t.csv"

# this will clycle throught the data inside the object $csvdata
foreach ($result in $csvdata) {
    # to access the data just refer to object $result.[columns names inside CSV]

    # Build task info
    $action  = New-ScheduledTaskAction -Execute "$($result.fullpath)" -Argument 'case there is any argument'
    $trigger = New-ScheduledTaskTrigger -Daily -At 9am 
    Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $($result.reportname) -Description $($result.reportname)
    # create the task scheduler
    New-ScheduledTaskAction -Execute 
}

任务创建部分基于:https://blogs.technet.microsoft.com/heyscriptingguy/2015/01/13/use-powershell-to-create-scheduled-tasks/

【讨论】:

  • 你进入 powershell 真是太棒了。但请记住,这里的解决方案是模糊的,用户似乎无法做一些简单的事情,比如解析 CSV 中的数据。还要查看此脚本,您应该更多地查看管道 |。许多这些命令可以链接在一起,以使脚本更有效、更易于阅读。
  • 但是 $result 的 powershell 怎么知道它是结果呢?它在哪里声明?
  • RWaternelon。听起来您对脚本很陌生。您应该阅读我提供的回复,然后从那里提问。至于 $Result 那是一个 foreach 语句,它遍历一个 psobject 以一次获取一个结果。
  • @ortolar:感谢您的输入,但使用 powershell 命令不起作用。我会尝试使用 schtasks 来实现。
猜你喜欢
  • 2011-02-26
  • 2023-03-15
  • 2019-12-24
  • 2019-05-02
  • 2021-02-04
  • 2018-01-12
  • 2017-07-02
  • 2014-12-28
  • 2022-12-01
相关资源
最近更新 更多