使用PowerShell调用VisualCron API导出设置时遇空值调用错误求助
问题:PowerShell调用VisualCron API导出设置时出现空值错误
我通过PowerShell调用VisualCron API编写函数导出所有设置,加载DLL和建立连接的函数可正常运行,但调用ExportSettings()方法时始终报空值错误。
我的PowerShell代码
#Function that loads VisualCron's API dlls. function Load-VCAPIDLL { param( [Parameter()] [string]$VCPath = "C:\Program Files (x86)\VisualCron\VisualCron.dll", [Parameter()] [string]$VCAPIPath = "C:\Program Files (x86)\VisualCron\VisualCronAPI.dll" ) $VC = [Reflection.Assembly]::LoadFrom($VCPath); $VCAPI = [Reflection.Assembly]::LoadFrom($VCAPIPath); } #Returns a VisualCronAPI.Server object that can be used to interact with target VisualCron server. function ConnectTo-VCServer { param( [Parameter(Mandatory=$true)] [string]$username, [Parameter(Mandatory=$true )] [string]$password, [Parameter( Mandatory=$true)] [alias("address")] [string]$VCServerAddress, [Parameter( Mandatory=$true )] [alias("connection")] [string]$VCServerConntype, [Parameter()] [alias("port")] [string]$VCServerPort ) #Call the dll loading fn Load-VCAPIDLL #Create new connection objects $ClientConnectionObj =New-Object -TypeName VisualCronAPI.Client $ServerConnectionObj = New-Object -TypeName VisualCronAPI.Server $APIConnectionObj = New-Object -TypeName VisualCronAPI.Connection #Assign provided params to APIConnectionObj $APIConnectionObj.Address = $VCServerAddress $APIConnectionObj.UserName = $username $APIConnectionObj.PassWord = $password if ($VCServerPort -ne $null) { $APIConnectionObj.Port } $APIConnectionObj.ConnectionType = $VCServerConntype #Using the ClientConnectionObj, pass in the APIConnectionObj to update ServerConnectionObj. #This creates a connection to the target VisualCron server. $ServerConnectionObj = $ClientConnectionObj.Connect($APIConnectionObj, $true) #Return VisualCronAPI.Server object Return $ServerConnectionObj } ##Export VisualCron settings to import in QA environment function Export-VCSettings { param( [Parameter(Mandatory=$true)] [string]$Usedefaultfile, [Parameter(Mandatory=$true )] [string]$IncludeallConnections, [Parameter( Mandatory=$true)] [string]$IncludeAllCredentials, [Parameter( Mandatory=$true )] [alias("Svrsettings")] [string]$IncludeAllServerSettings, [Parameter()] [alias("InclAllJobs")] [string]$IncludeAllJobs, [Parameter()] [alias("InclAllPerm")] [string]$IncludeallPermissions, [Parameter()] [alias("IncludeCerts")] [string]$IncludeAllCertificates, [Parameter()] [alias("JobObjects")] [string]$Jobjcts ) { $global:Server = New-Object VisualCronAPI.Server $eip = New-Object VisualCron.ExportImportProgressClass $eip.UseDefaultFile = $Usedefaultfile $eip.IncludeAllCertificates = "true" $eip.IncludeAllConnections = $IncludeallConnections $eip.IncludeAllCredentials = $IncludeAllCredentials, $eip.IncludeAllServerSettings = $IncludeAllServerSettings $eip.IncludeAllJobs = $IncludeAllJobs $eip.IncludeAllPermissions = $IncludeallPermissions $eip.JobObjects = $global:Server.jobs.GetAll() } $escr = New-Object VisualCron.ExportSettingsResponseClass $escr = $global:Server.ExportSettings($eip) if ($escr.Success -and $escr.FileBytes -ne 'null') { [system.IO.File.Writeallbytes]::("c:\VC-Settings.zip", $escr.FileBytes) }} Export-VCSettings -Usedefaultfile $true -IncludeallConnections $true -IncludeAllCredentials $true -IncludeAllServerSettings $true -IncludeAllJobs $true -IncludeallPermissions $true -IncludeAllCertificates $true -Jobjcts "all"
报错信息
You cannot call a method on a null-valued expression. At line:47 char:1 + $escr = $global:Server.ExportSettings($eip) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull
参考的C#示例代码
if (s.Connected) { Console.WriteLine("Connected to Server"); ExportImportProgressClass eip = new ExportImportProgressClass(); eip.UseDefaultFile = false; eip.IncludeAllCertificates = false; eip.IncludeAllConditions = false; eip.IncludeAllConnections = false; eip.IncludeAllCredentials = false; eip.IncludeAllExitCodes = false; eip.IncludeAllNetworkDrives = false; eip.IncludeAllNotifications = false; eip.IncludeAllPermissions = false; eip.IncludeAllPGPKeyRings = false; eip.IncludeAllServerSettings = false; eip.IncludeAllTimeExceptions = false; eip.IncludeAllUserGroups = false; eip.IncludeAllVariables = false; eip.IncludeAllJobs = false; /*var jobs = (from j in s.Jobs.GetAll() where j.Group == "WD Standard" select j.Name).ToList();*/ //eip.Jobs = jobs; //eip.JobObjects = s.Jobs.GetAll().Where(item => item.Group == "WD Standard").ToList(); eip.JobObjects = s.Jobs.GetAll(); ExportSettingsResponseClass esrc = s.ExportSettings(eip); if (esrc.Success && esrc.FileBytes != null) { System.IO.File.WriteAllBytes("C:/Temp/VC-Settings.zip", esrc.FileBytes); } s.Disconnect(); }
问题分析与修复方案
核心问题
报错的直接原因是$global:Server未建立有效连接或为空,导致无法调用ExportSettings()方法。具体问题点如下:
未使用已连接的Server实例
在Export-VCSettings里直接新建空的VisualCronAPI.Server对象,该对象未与服务器建立连接,完全无效。应使用ConnectTo-VCServer函数返回的已连接的Server实例。参数类型不匹配
ExportImportProgressClass的属性均为布尔类型(bool),但函数参数定义为string类型,传入的字符串无法正确转换为布尔值,导致属性赋值异常。语法错误
$eip.IncludeAllCredentials = $IncludeAllCredentials后多了一个逗号,导致该属性被赋值为数组,破坏对象结构。不必要的代码块导致作用域问题
Export-VCSettings里嵌套的额外{}代码块,限制了$eip等变量的作用域,外部访问时可能出现异常。JobObjects获取逻辑错误
空Server对象调用jobs.GetAll()必然返回空,且会引发潜在错误,必须用已连接的Server实例调用该方法。
修复后的代码示例
1. 修改Export-VCSettings函数
function Export-VCSettings { param( [Parameter(Mandatory=$true)] [bool]$UseDefaultFile, [Parameter(Mandatory=$true )] [bool]$IncludeAllConnections, [Parameter(Mandatory=$true)] [bool]$IncludeAllCredentials, [Parameter(Mandatory=$true )] [alias("Svrsettings")] [bool]$IncludeAllServerSettings, [Parameter()] [alias("InclAllJobs")] [bool]$IncludeAllJobs, [Parameter()] [alias("InclAllPerm")] [bool]$IncludeAllPermissions, [Parameter()] [alias("IncludeCerts")] [bool]$IncludeAllCertificates, [Parameter(Mandatory=$true)] [VisualCronAPI.Server]$ConnectedServer ) $eip = New-Object VisualCron.ExportImportProgressClass $eip.UseDefaultFile = $UseDefaultFile $eip.IncludeAllCertificates = $IncludeAllCertificates $eip.IncludeAllConnections = $IncludeAllConnections $eip.IncludeAllCredentials = $IncludeAllCredentials $eip.IncludeAllServerSettings = $IncludeAllServerSettings $eip.IncludeAllJobs = $IncludeAllJobs $eip.IncludeAllPermissions = $IncludeAllPermissions # 仅当不需要导出全部Job时设置,IncludeAllJobs为true时无需赋值 if (-not $IncludeAllJobs) { $eip.JobObjects = $ConnectedServer.Jobs.GetAll() } $escr = $ConnectedServer.ExportSettings($eip) if ($escr.Success -and $escr.FileBytes -ne $null) { [system.IO.File]::WriteAllBytes("c:\VC-Settings.zip", $escr.FileBytes) Write-Host "设置导出成功,文件路径:c:\VC-Settings.zip" } else { Write-Host "导出失败:$($escr.Message)" } }
2. 正确的调用流程
先建立连接,再传入已连接的Server实例调用导出函数:
# 先连接到VisualCron服务器 $connectedServer = ConnectTo-VCServer -username "你的用户名" -password "你的密码" -VCServerAddress "服务器地址" -VCServerConntype "连接类型(如Http/Tcp)" -VCServerPort "端口号" # 调用导出函数 Export-VCSettings -UseDefaultFile $true -IncludeAllConnections $true -IncludeAllCredentials $true -IncludeAllServerSettings $true -IncludeAllJobs $true -IncludeAllPermissions $true -IncludeAllCertificates $true -ConnectedServer $connectedServer
额外注意事项
- 确保
ConnectTo-VCServer返回的$connectedServer不为null,且$connectedServer.Connected为$true,再调用导出函数。 - 若需导出指定Job,可调整
JobObjects的赋值逻辑,比如过滤特定组或名称的Job。 - 导出路径
c:\VC-Settings.zip需要当前用户有写入权限,否则会报错,可改为有权限的路径(如$env:TEMP\VC-Settings.zip)。
内容的提问来源于stack exchange,提问作者Rami Aboulissane
相关产品推荐
相关产品推荐

