You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在同一份PowerShell脚本中同时运行两个函数?含双数据库查询需求

在PowerShell中异步运行本地数据库查询与Dynamics CRM在线查询的方案

嘿,我完全懂你在PowerShell里搞异步双查询的痛苦——一边是本地数据库,一边是Dynamics CRM在线连接,两种不同的数据源要同时跑,确实容易踩坑。我之前处理过类似场景,给你分享几个实测有效的方案:

方案1:使用Start-Job(兼容PowerShell 5.x和7+)

Start-Job会创建独立的后台作业,适合隔离两个不同的查询任务。需要注意的是,每个作业都是独立进程,所以要在作业内部重新初始化连接(不能直接复用当前会话的CRM或DB连接)。

示例代码:

# 定义本地数据库查询的作业
$localDbJob = Start-Job -ScriptBlock {
    # 加载SqlClient模块(如果需要)
    Import-Module SqlServer -ErrorAction SilentlyContinue

    $connectionString = "Server=.\SQLEXPRESS;Database=LocalDB;Integrated Security=True;"
    $query = "SELECT TOP 10 * FROM Customers;"

    $connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
    $command = New-Object System.Data.SqlClient.SqlCommand($query, $connection)
    
    $connection.Open()
    $reader = $command.ExecuteReader()
    $results = @()
    while ($reader.Read()) {
        $row = [PSCustomObject]@{
            ID = $reader["ID"]
            Name = $reader["Name"]
            Email = $reader["Email"]
        }
        $results += $row
    }
    $connection.Close()
    return $results
}

# 定义Dynamics CRM在线查询的作业
$crmJob = Start-Job -ScriptBlock {
    # 加载Dynamics CRM模块(比如Microsoft.Xrm.Data.PowerShell)
    Import-Module Microsoft.Xrm.Data.PowerShell -ErrorAction Stop

    # CRM连接参数
    $crmUrl = "https://yourorg.crm.dynamics.com"
    $credential = Get-Credential -Message "Enter CRM credentials"

    # 建立CRM连接
    $conn = Connect-CrmOnline -Credential $credential -ServerUrl $crmUrl

    # 执行CRM查询(比如获取账户记录)
    $query = @"
<fetch top='10'>
  <entity name='account'>
    <attribute name='accountid' />
    <attribute name='name' />
    <attribute name='emailaddress1' />
  </entity>
</fetch>
"@
    $crmResults = Get-CrmRecordsByFetch -Fetch $query -conn $conn
    return $crmResults.CrmRecords
}

# 等待两个作业完成
Wait-Job $localDbJob, $crmJob

# 获取作业结果
$localResults = Receive-Job $localDbJob
$crmResults = Receive-Job $crmJob

# 处理结果
Write-Host "本地数据库查询结果:"
$localResults | Format-Table -AutoSize

Write-Host "`nDynamics CRM查询结果:"
$crmResults | Format-Table -AutoSize

# 清理作业
Remove-Job $localDbJob, $crmJob

方案2:使用ForEach-Object -Parallel(PowerShell 7+专属)

如果你用的是PowerShell 7或更高版本,ForEach-Object -Parallel语法更简洁,性能也更好(基于.NET Tasks,比Start-Job轻量)。

示例代码:

# 定义两个任务的配置
$tasks = @(
    @{
        Type = "LocalDB"
        ConnectionString = "Server=.\SQLEXPRESS;Database=LocalDB;Integrated Security=True;"
        Query = "SELECT TOP 10 * FROM Customers;"
    },
    @{
        Type = "CRM"
        Url = "https://yourorg.crm.dynamics.com"
        Credential = Get-Credential -Message "Enter CRM credentials"
        FetchQuery = @"
<fetch top='10'>
  <entity name='account'>
    <attribute name='accountid' />
    <attribute name='name' />
    <attribute name='emailaddress1' />
  </entity>
</fetch>
"@
    }
)

# 并行执行任务
$results = $tasks | ForEach-Object -Parallel {
    switch ($_.Type) {
        "LocalDB" {
            Import-Module SqlServer -ErrorAction SilentlyContinue
            $conn = New-Object System.Data.SqlClient.SqlConnection($_.ConnectionString)
            $cmd = New-Object System.Data.SqlClient.SqlCommand($_.Query, $conn)
            $conn.Open()
            $reader = $cmd.ExecuteReader()
            $output = @()
            while ($reader.Read()) {
                $output += [PSCustomObject]@{
                    Source = "LocalDB"
                    ID = $reader["ID"]
                    Name = $reader["Name"]
                    Email = $reader["Email"]
                }
            }
            $conn.Close()
            return $output
        }
        "CRM" {
            Import-Module Microsoft.Xrm.Data.PowerShell -ErrorAction Stop
            $crmConn = Connect-CrmOnline -Credential $_.Credential -ServerUrl $_.Url
            $crmOutput = Get-CrmRecordsByFetch -Fetch $_.FetchQuery -conn $crmConn
            return $crmOutput.CrmRecords | ForEach-Object {
                [PSCustomObject]@{
                    Source = "CRM"
                    AccountID = $_.accountid
                    AccountName = $_.name
                    Email = $_.emailaddress1
                }
            }
        }
    }
} -ThrottleLimit 2

# 输出合并后的结果
$results | Format-Table -AutoSize

关键注意事项

  • 连接隔离:不管用哪种方法,后台任务/并行进程都无法继承当前会话的数据库或CRM连接,必须在每个任务内部重新初始化连接。
  • 模块加载:确保在任务内部加载所需的模块(比如SqlServer或Microsoft.Xrm.Data.PowerShell),因为后台进程的模块环境是独立的。
  • 权限问题:本地数据库查询要确保后台作业的运行账户有访问权限;CRM连接要确认凭据正确,并且网络能访问Dynamics CRM在线端点。
  • 调试技巧:如果任务失败,可以用Receive-Job -Job $job -ErrorVariable err或者在并行块里添加Write-Error来捕获错误信息。

内容的提问来源于stack exchange,提问作者KhaleesiJen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:23:47