Parametrizando parâmetros do PowerShell em tarefas agendadas

1

Tenho vários scripts do PowerShell que são iniciados por meio de tarefas agendadas em vários momentos.

O script é executado várias vezes com argumentos diferentes. Também os administradores não familiarizados com o script precisam alterar os parâmetros sem precisar editar o código.

Devido a esse requisito, passei os parâmetros por meio de argumentos para o powershell.exe em tarefas agendadas. Mas isso imediatamente tornou-se pesado, porque agora para alterar os parâmetros de um script você tem que ir para o agendador de tarefas e editar os argumentos para powershell.exe que agora se parece com isso (na verdade ainda mais):

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

Então, agora, o que eu quero fazer é que cada script pegue apenas um arquivo de configuração editável, onde os parâmetros podem ser alterados pelos administradores. Eu também poderia organizar os parâmetros com mais facilidade - ter um arquivo de configuração de parâmetros "global" usado por todos os scripts e, em seguida, arquivos de configuração específicos do script.

Eu pensei em usar JSON nos arquivos de configuração e estava pensando em fazer algo assim:

{
    "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)

Desta forma, na tarefa agendada, tenho apenas um argumento para passar (o caminho do arquivo de configuração). Isso parece funcionar, mas eu queria perguntar se havia uma maneira melhor e mais sadia de atingir meus objetivos. Há algo de tolo nessa abordagem que não estou vendo?

    
por red888 30.04.2014 / 19:18

1 resposta

2

O que você está fazendo faz sentido; ninguém precisa mexer com o script (o que pode introduzir problemas de código), ou com a tarefa agendada (o que pode exigir que eles saibam as credenciais da conta "run as", e também é complicado para aqueles que não conhecem).

Ter o caminho do arquivo de configuração passado como parâmetro também faz sentido; Dessa forma, você pode reutilizar seu script com diferentes configurações facilmente; então você não está restrito a um único "conjunto de parâmetros" a qualquer momento, mas pode ter um conjunto de parâmetros (arquivo de configuração) por tarefa agendada.

Possível problema

Seu JSON inclui o tipo de dados; por exemplo, "folder1": ["string","C:\sldks\dsf\sdf\sdf\sd\fsdf\"] . Por quê? Você terá definido os tipos em seu arquivo PS de qualquer maneira (se necessário); na sua configuração, você só quer manter os dados sem exigir que seus administradores saibam que "string" significa "texto" / sem ter que pensar sobre isso. ou seja, só tem "folder1": "C:\sldks\dsf\sdf\sdf\sd\fsdf\" .

Existem algumas considerações adicionais:

  • JSON vs XML vs INI vs Database vs Outros. Quais tipos de arquivos / tecnologias são os seus administradores mais familiarizados com / o que eles acham mais fácil de manipular? Pessoalmente, eu usaria XML para isso; O PS é tão confortável quanto isso, mas a vantagem é que seus administradores podem abri-lo em um navegador e ver imediatamente se é um XML válido ou não (ou seja, se eles perderam uma tag de fechamento / algo incorreto). Dito isso, isso depende muito das habilidades / preferências / ferramentas de sua equipe.

  • Validação. O que acontece se alguém inserir dados incorretos ou corromper o formato de arquivo (por exemplo, perder um colchete) ou corromper o arquivo (por exemplo, salvar em ANSI em vez de UTF8 / whatever)? Certifique-se de que seu script tenha algo para lidar com isso; e também considere como você descobriria; Ou seja, assim como "não execute se a configuração tiver problemas", você deseja "relatar um problema para que eu possa investigar e corrigi-lo se a configuração tiver problemas".

  • Escapando personagem. No exemplo acima, você precisou escapar do caminho do arquivo: C:\sldks\dsf\sdf\sdf\sd\fsdf\ em vez de C:\sldks\dsf\sdf\sdf\sd\fsdf\ . Os administradores saberiam fazer isso / saber quais caracteres devem ser salvos para o formato do arquivo de configuração? Se você tiver uma ferramenta (genérica) para editar esses arquivos, o que eliminará a dor e poupará algumas preocupações; caso contrário, veja o ponto acima na validação.

  • Segurança. As pastas que contêm seus scripts e seus arquivos de configuração estão adequadamente protegidos; caso contrário, as pessoas podem manipular seu código para fazer o que quiserem enquanto estão executando a conta "executar como" da tarefa. Se as pessoas que editam a configuração forem diferentes dos scripts de edição, provavelmente é melhor mantê-las em diretórios separados para limitar o que cada pessoa pode fazer.

A maioria dessas coisas ainda seria considerações se passar parâmetros; então o seu caminho é definitivamente um passo em frente, independentemente das considerações acima; mas se você quiser fazer algo realmente amigável e robusto, levar em conta os pontos acima irá ajudar.

    
por 04.11.2016 / 10:24