在计划任务中参数化 PowerShell 参数

在计划任务中参数化 PowerShell 参数

我有一堆 PowerShell 脚本,它们通过计划任务在不同时间启动。

脚本使用不同的参数运行多次。不熟悉脚本的管理员也需要能够更改参数而无需编辑代码。

由于这个要求,我通过计划任务中的 powershell.exe 参数传递了参数。但这立即变得难以处理,因为现在要更改脚本的参数,您必须进入任务计划程序并编辑 powershell.exe 的参数,现在看起来像这样(实际上更长):

-command "& 'C:\some\file\path\' -param1 'C:\some\file\path\' -param2 'C:\soawme\fawdile\pawawasth\' -param3 'C:\some\fisdfle\pasdfth\' -param4 'some arg'"

所以现在我想要做的是让每个脚本只接受一个可编辑的配置文件,其中的参数可以由管理员更改。我还可以更轻松地组织参数 - 拥有一个所有脚本都使用的“全局”参数配置文件,然后是特定于脚本的配置文件。

我以为我会用JSON在配置文件中,并考虑做这样的事情:

{
    "folder1":  [
                    "string",
                    "C:\\sldks\\dsf\\sdf\\sdf\\sd\\fsdf\\"
                ],
    "folder2":  [
                    "string",
                    "C:\\jiji\\sfef\\igig\\igg\\"
                ],
    "CSSFile":  [
                    "string",
                    "\\\\some\\netqwork\\path\\"
                ],
    "DBServer":  [
                     "string",
                     "myserver"
                 ],
    "DB":  [
               "string",
               "DB"
           ],
    "SqlQuery":  [
                     "string",
                     "SELECT * FROM myTable"
                 ],
    "UID":  [
                "string",
                "root"
            ],
    "PWD":  [
                "string",
                "123456"
            ]
}

$jsonObject = ConvertFrom-Json (cat $PathToMyExternalJsonFilePassedInFromTaskShedualer)

    function Set-ParamType ($jsonNode) {
        switch ($jsonNode[0])
        {
            'string' {return [string]$jsonNode[1]}
            'int' {return [int]$jsonNode[1]}
            'switch' {return [switch]$jsonNode[1]}
            default {"Debug: Unknown type"}
        }
    }

    $folder1  = Set-ParamType($jsonObject.folder1)
    $folder2  = Set-ParamType($jsonObject.folder2)
    $CSSFile  = Set-ParamType($jsonObject.CSSFile)
    $DBServer = Set-ParamType($jsonObject.DBServer)
    $DB       = Set-ParamType($jsonObject.DB)
    $SqlQuery = Set-ParamType($jsonObject.SqlQuery)
    $UID      = Set-ParamType($jsonObject.UID)
    $PWD      = Set-ParamType($jsonObject.PWD)

这样,在计划任务中我只需要传入一个参数(配置文件的路径)。这似乎可行,但我想问一下是否有更好、更明智的方法来实现我的目标。这种方法是否有什么愚蠢之处我没有发现?

答案1

你所做的是有意义的;没有人需要摆弄脚本(这可能会引入代码问题)或计划任务(这可能要求他们知道“以...身份运行”帐户的凭据,并且对那些不熟悉的人来说尤其麻烦)。

将配置文件路径作为参数传递也是有意义的;这样您可以轻松地重复使用具有不同配置的脚本;因此您不会在任何时候局限于单个“参数集”,而是每个计划任务可以有一组参数(配置文件)。

可能的问题

您的 JSON 包含数据类型;例如"folder1": ["string","C:\\sldks\\dsf\\sdf\\sdf\\sd\\fsdf\\"]。为什么?无论如何,您都会在 PS 文件中定义类型(如果需要);在您的配置中,您只想保存数据,而不需要您的管理员知道“字符串”表示“文本”/而不必考虑它。即,只要有"folder1": "C:\\sldks\\dsf\\sdf\\sdf\\sd\\fsdf\\"

还有一些其他注意事项:

  • JSONvs XMLvs INIvs Databasevs 其他。您的管理员最熟悉哪种文件/技术/他们觉得哪种文件/技术最容易操作?我个人会使用 XML;PS 也同样适合使用它,但优点是您的管理员可以在浏览器中打开它并立即查看它是否是有效的 XML(即他们是否错过了结束标记/拼错了某些内容)。也就是说,这在很大程度上取决于您团队的能力/偏好/工具。

  • 验证。如果有人输入了错误数据,或者破坏了文件格式(例如,遗漏了一个括号),或者破坏了文件(例如,以 ANSI 而不是 UTF8 保存/等等),会发生什么情况?确保您的脚本可以处理这种情况;同时考虑如何发现;例如,除了“如果配置有问题,则不要运行”,您还需要“报告问题,以便我可以调查并修复配置有问题的问题”。

  • 字符转义。在上面的例子中,您必须转义文件路径:C:\\sldks\\dsf\\sdf\\sdf\\sd\\fsdf\\而不是C:\sldks\dsf\sdf\sdf\sd\fsdf\。管理员是否知道要这样做/知道要为配置文件的格式转义哪些字符?如果您有一个(通用)工具来编辑此类文件,可以减轻您的麻烦,这将为您省去一些顾虑;否则,请参阅上面关于验证的要点。

  • 安全性。包含脚本和配置文件的文件夹是否得到适当的保护;否则人们可以在任务的“以...身份运行”帐户下运行时操纵您的代码以执行他们想要的操作。如果编辑配置的人与编辑脚本的人不同,最好将他们放在不同的目录中,以限制每个人可以执行的操作。

如果传递参数,大多数这些事情仍然需要考虑;所以无论上述考虑如何,你的方法肯定会更上一层楼;但如果你想要制作一些真正友好和强大的东西,考虑上述几点会有所帮助。

相关内容