我有一长串我想有点自动化的简单工作。这很简单,可以通过API获取或发布信息,并生成一些报告,没什么花哨的。
我决定构建一个主脚本,该脚本可以定向到各种其他脚本,每个脚本都处理自己的工作。这些小脚本中的每个脚本都引用了我构建的 Utility 脚本中的功能,该脚本具有所有其他简单作业脚本所共有的功能。
当我直接运行它们时,每个脚本都能完美地工作,但是,当我尝试通过主脚本(路由到它们)运行它们时,它们都会失败。
一个例子是,在许多情况下,我需要从API提取数据,但是当我需要10k +时,会被限制为1000个对象返回。为了解决这个问题,我构建了一个函数,该函数递归调用自身,直到没有更多数据可收集为止。再次说明,此方法可以单独调用,但不能从主脚本中调用,由于某种原因,它在第一次运行后无法运行(在这种情况下应运行10次以上)。然后,它什么也不返回。
我想这可能与我确定函数/变量的范围有关吗?不确定。我尝试将范围设定为Global, Local & Script
,但似乎没有任何作用。这是一些代码...
*Master Director Script runs script based on user input*
...
&$choice_hash[$action].script_path
$ScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
. "$ScriptDirectory\Utilities.psm1"
$user_data = $null
$env_choice = $null
$csv_output_path = $null
$collated_user_data = [System.Collections.ArrayList]@()
function selectEnv {
$global:env_choice = Read-Host @"
> Select an Environment: [Prod] or [Dev]
Your Choice
"@
if ($env_choice -ne 'Prod' -and $env_choice -ne 'Dev') {
consoleCmt $env_choice
consoleCmt 'Invalid Choice. Try again...'
selectEnv
} else {
if ($env_choice -eq 'Prod') {
$global:csv_output_path = '\\etoprod\******\Exports\Report_Users_Prod.csv'
} else {
$global:csv_output_path = '\\etoprod\******\Exports\Report_Users_Dev.csv'
}
$global:user_data = process_data $env_choice 'api/xm/1/people?embed=roles&limit=1000'
}
}
function processUsersData {
foreach($user in $user_data) {
$user_roles = ''
$role_divider = ','
for($i = 0; $i -lt $user.roles.data.length; $i++) {
# Only append a comma if there are more, otherwise leave blank for CSV deliniation
if ($i -eq $user.roles.data.length - 1) {
$role_divider = ''
}
$user_roles += $user.roles.data[$i].name + $role_divider
}
# Build ordered hash table with above data
$sanatized_user = [pscustomobject][ordered]@{id = $user.targetName; firstName = $user.firstName; lastName = $user.lastName; siteName = $user.site.name; roles = $user_roles }
# Shovel into storage array used for building the CSV
$global:collated_user_data += $sanatized_user
}
}
notice 'Initiating Groups Report Script'
selectEnv
processUsersData
exportCsv $collated_user_data $csv_output_path
实用脚本(正在调用相关功能)
$res = $null
$content = @()
...
function process_data($env, $url) {
fetch_data $env $url
foreach($i in $res.data) {
$global:content += $i
}
if($res.links.next) {
fetch_more $env $res.links.next
}
return $content **Should return full collection of data, but fails after one pass**
}
function fetch_data($env, $url) {
$base = generateEnvBase $env
$path = "$base/$url"
$req = Invoke-WebRequest -Credential $cred -Uri $path -Method GET
$global:res = ConvertFrom-Json $req
}
function fetch_more($env, $url) {
$base = generateEnvBase $env
$path = "$base$url"
$req = Invoke-WebRequest -Credential $cred -Uri $path -Method GET
$res = ConvertFrom-Json $req
foreach($i in $res.data) {
$global:content += $i
}
if($res.links.next) {
fetch_more $env $res.links.next
}
}
答案 0 :(得分:0)
对不起,如果我没有遵循程序或礼节,我是新来的。
如果您在Main.ps1中声明函数需要的所有变量,则此方法应该起作用。在要在函数外部使用的函数内部创建新变量时,也可以使用“脚本”作用域。在函数内部创建的示例$Script:Var = "Stuff"
将可用于整个脚本。
目录结构
C:\Script\Root
| Main.ps1
\---Utilities
fetch_data.ps1
fetch_more.ps1
processUsersData.ps1
process_data.ps1
selectEnv.ps1
Main.ps1
#---[ Initization ]---#
# Strings
[String]$RootPath = $PSScriptRoot
[String]$UtilPath = "$($RootPath)\Utilities"
[String]$env_choice = $null
[String]$csv_output_path = $null
# Arrays
[Array]$user_data = @()
[Array]$content = @()
[Array]$collated_user_data = @()
[Array]$res = @()
#---[ Source in Utilities ]---#
# Get the scripts
$Utilities = Get-ChildItem -Path "$UtilPath" -File | Where-Object {$_.Extension -eq ".ps1"}
# Source in each one
foreach ($Item in $Utilities) {
.$Item.FullName
}
#---[ Select an Environment ]---#
# Get the User's choice
$env_choice = selectEnv
# Process the choice
switch ($env_choice) {
Prod {
$csv_output_path = '\\etoprod\******\Exports\Report_Users_Prod.csv'
$user_data = process_data 'Prod' 'api/xm/1/people?embed=roles&limit=1000'
}
Dev {
$csv_output_path = '\\etoprod\******\Exports\Report_Users_Dev.csv'
$user_data = process_data 'Dev' 'api/xm/1/people?embed=roles&limit=1000'
}
Test {
Write-Output "Test is not an option. Choose wisely."
exit 1
}
Default {
Write-Output "Unknown Environment Choice."
exit 1
}
}
#---[ Process Users and Export ]---#
processUsersData
exportCsv $collated_user_data $csv_output_path
selectEnv.ps1
function selectEnv {
$Title = "Environment:"
$Info = "Please choose an environment"
# Options
$Prod = New-Object System.Management.Automation.Host.ChoiceDescription '&Prod', 'Production environment'
$Dev = New-Object System.Management.Automation.Host.ChoiceDescription '&Dev', 'Development environment'
$Test = New-Object System.Management.Automation.Host.ChoiceDescription '&Test', 'Testing environment'
$Options = [System.Management.Automation.Host.ChoiceDescription[]]($Prod, $Dev, $Test)
$Default = 0
# Promp the User
$Choice = $host.UI.PromptForChoice($Title , $Info , $Options, $Default)
$Result = $Options[$Choice].Label -Replace '&',''
return $Result
}