您如何将 SQL 服务器代理作业编写成单个文件或单个文件

How do you script out SQL Server agent jobs to single or individual files

我尝试了各种 Powershell 脚本,但都失败了:

The following exception occurred while trying to enumerate the collection: "An exception occurred while executing a Transact-SQL statement or batch.".

At H:\Create_SQLAgentJobSripts2.ps1:89 char:22

  • foreach ($job in $s.JobServer.Jobs)  
    
  •                  ~~~~~~~~~~~~~~~~~  
    
  • CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException
  • FullyQualifiedErrorId : ExceptionInGetEnumerator

出了什么问题或者我怎样才能更好地调试这个错误?

我执行了这个脚本:

.\Create_SQLAgentJobSripts2.ps1 .\ServerNameList.txt

这是脚本

param([String]$ServerListPath)

#write-host "Parameter: $ServerListPath"
 
#Load the input file into an Object array
$ServerNameList = get-content -path $ServerListPath

#Load the SQL Server SMO Assemly
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null

#Create a new SqlConnection object
$objSQLConnection = New-Object System.Data.SqlClient.SqlConnection

#For each server in the array do the following.
foreach($ServerName in $ServerNameList)
{
    Write-Host "Beginning with Server: $ServerName"

    Try
    {
        $objSQLConnection.ConnectionString = "Server=$ServerName;Initial Catalog=CED_NCT_RESOURCE_TRACK;Persist Security Info=True;User ID=CEDNCTAdmin;Password=CEDNCTAdmin;"
            Write-Host "Trying to connect to SQL Server instance on $ServerName..." -NoNewline
            $objSQLConnection.Open() | Out-Null
            Write-Host "Success."
        $objSQLConnection.Close()
    }
    Catch
    {
        Write-Host -BackgroundColor Red -ForegroundColor White "Fail"
        $errText =  $Error[0].ToString()
            if ($errText.Contains("network-related"))
        {Write-Host "Connection Error. Check server name, port, firewall."}
 
        Write-Host $errText
        continue
    }

    # Won't be using this object again
    Remove-Variable -Name objSQLConnection
 
    #If the output folder does not exist then create it
    $OutputFolder = ".$ServerName"
    if (!(Test-Path $OutputFolder))
    {
        write-host ("Creating directory: " + $OutputFolder)
        New-Item -ItemType directory -Path $OutputFolder
    }
    else
    {
        write-host ("Directory already exists: " + $OutputFolder)
    }

    write-host "File: $(".$OutputFolder\" + $($_.Name -replace '\', '') + ".job.sql")"

    # Connect to the instance using SMO
    $s = new-object ('Microsoft.SqlServer.Management.Smo.Server') $ServerName

    write-host ("SQL Server Edition: " + $s.Edition)
    write-host ("SQL Agent ErrorLogFile: " + $s.JobServer.ErrorLogFile)
    
    # Instantiate the Scripter object and set the base properties
    $scrp = new-object ('Microsoft.SqlServer.Management.Smo.Scripter') ($ServerName)

    write-host ("SCRP ToString():" + $scrp.ToString())
    write-host ("Test scrp - Server: " + $scrp.Server)

    #The next step is to set the properties for the script files:
    $scrp.Options.ScriptDrops = $False
    $scrp.Options.WithDependencies = $False
    $scrp.Options.IncludeHeaders = $True
    $scrp.Options.AppendToFile = $False
    $scrp.Options.ToFileOnly = $True
    $scrp.Options.ClusteredIndexes = $True
    $scrp.Options.DriAll = $True
    $scrp.Options.Indexes = $False
    $scrp.Options.Triggers = $False
    $scrp.Options.IncludeIfNotExists = $True

    #Now, we can cycle through the jobs and create scripts for each job on the server.

    # Create the script file for each job
    foreach ($job in $s.JobServer.Jobs)
    {
        $jobname = $job.Name
        
         write-host ("Job: " + $jobname)

        $jobfilename = ($OutputFolder + "\" + $jobname + ".job.sql")
        $scrp.Options.FileName = $jobfilename

         write-host "Filename: $jobfilename"

        #This line blows up
        $scrp.Script($job)
    }
}

可能您没有正确实例化 Server 对象。请尝试以下操作...

# Alternative 1: With servername and port, using Trusted Connection...
$ServerName = 'YourServerName,1433'
$ServerConnection = New-Object  Microsoft.SqlServer.Management.Common.ServerConnection -ArgumentList @( $ServerName )

# Alternative 2: With an SqlConnection object
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=$ServerName;Initial Catalog=CED_NCT_RESOURCE_TRACK;Persist Security Info=True;User ID=CEDNCTAdmin;Password=CEDNCTAdmin;"
$SqlConnection.Open() | Out-Null
$ServerConnection = New-Object  Microsoft.SqlServer.Management.Common.ServerConnection -ArgumentList @( $SqlConnection )

# Then...
$Server = New-Object Microsoft.SqlServer.Management.Smo.Server -ArgumentList @( $ServerConnection )
$Server.JobServer.Jobs | ForEach-Object {
    Write-Host "Job: $($_.Name)"
}