Ausführen eines Powershell-Skripts vom SQL Server-Agenten im Jahr 2014 mithilfe meines AD-Kontos über einen Berechtigungsnachweis. Ich erhalte den folgenden Fehler.
Ein Jobschritt hat in Zeile 1 eines PowerShell-Skripts einen Fehler erhalten. Die entsprechende Zeile lautet 'set-executepolicy RemoteSigned -scope process -Force'. Korrigieren Sie das Skript und planen Sie den Job neu. Die von PowerShell zurückgegebenen Fehlerinformationen lauten: 'Sicherheitsfehler.
Meine Suchanfragen bei Google haben nichts Nützliches ergeben. Ich kann das Skript problemlos über SSMS auf meiner Workstation über die Powershell-Konsole ausführen.
Die Ausführungsrichtlinie ist auf uneingeschränkt festgelegt
PS C:\WINDOWS\system32> Get-ExecutionPolicy
Unrestricted
Die in der Fehlerausgabe erwähnte Zeile muss automatisch von SQL Server hinzugefügt werden, da sie RemoteSigned -scope process -Force
sich nirgendwo im Code befindet.
Gibt es noch etwas, das ich in SQL Server Agent festlegen muss, außer dass ich AD-Konto zum Ausführen des Jobs verwende?
Hier ist die Powershell-Reihe von msdb.dbo.syssubsystems
C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\SQLPS.exe
Aktualisieren
Hier ist die Version
PS SQLSERVER:\SQL\CD000023\CEF_2014_1> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
2 0 -1 -1
Update 01/03/2015
Dieses Skript erstellt eine Tabellenserverliste basierend auf den registrierten Servern eines zentralen Verwaltungsservers. Es stellt dann eine Verbindung zu jedem dieser Server her und identifiziert den Port, den es abhört.
# connection parameters
Param (
[string] $CMSServer="someuser\someinstance", # CMS server that stores serverlist
[string] $CMSDatabase="msdb", # database where the serverlist is stored
[string] $CMSUser="someuser", # username to connect to the cms server
[string] $CMSPassword="somepassword", # password to connect with the cmsuser
[string] $CMSTable="dbo.serverlist", # name of table that stores instances
[string] $CMSTableNoSchema="serverlist", # name of table that stores instances
[string] $UserName="remoteuser", # username to connect to each instance
[string] $Password="remotepassword", # password to connect to each instance
[string] $SrcDatabase="tempdb", # database where listening ports are stored
[string] $SrcTable="#listeningport" # table where listening ports are stored
)
# load in the SQL Server Powershell Module
[System.Reflection.Assembly]::LoadWithPartialName( `
"Microsoft.SqlServer.Smo");
# log file function
$logfile = "c:\temp\get_server_ports_$(get-date -format `"yyyy_MM_ddtt`").txt"
# initalize log file
$logfile | out-file -Filepath $logfile
function log($string, $color)
{
if ($Color -eq $null) {$color = "white"}
write-host $string -foregroundcolor $color
$string | out-file -Filepath $logfile -append
}
# CMS Server connection
$CMSServerConnectionString = "Data Source=$CMSServer;Initial Catalog=$CMSDatabase;User Id=$CMSUser;PWD=$CMSPassword;"
$CMSServerConnection = new-object system.data.SqlClient.SqlConnection($CMSServerConnectionString);
$CMSServerConnection.Open()
# create SMO objects so that tables can be created and dropped
$srv = new-Object Microsoft.SqlServer.Management.Smo.Server($CMSServerConnection)
$db = New-Object Microsoft.SqlServer.Management.Smo.Database
$db = $srv.Databases.Item($CMSDatabase)
# drop and recreate the serverlist Table on the CMS server
$tb = $db.Tables[$CMSTableNoSchema]
IF ($tb)
{$tb.Drop()}
# Create the serverlist Table on the cms server
$tb = new-object Microsoft.SqlServer.Management.Smo.Table($db, $CMSTableNoSchema)
$col1 = new-object Microsoft.SqlServer.Management.Smo.Column($tb, "server_name", [Microsoft.SqlServer.Management.Smo.DataType]::NChar(255))
$col2 = new-object Microsoft.SqlServer.Management.Smo.Column($tb, "server_port", [Microsoft.SqlServer.Management.Smo.DataType]::Int)
$tb.Columns.Add($col1)
$tb.Columns.Add($col2)
$tb.Create()
# collect the list of servers
$cmd4 = new-object System.Data.SQLClient.SQLCommand
$cmd4.CommandText = "
insert into msdb.dbo.serverlist (server_name, server_port)
select server_name, 1 from msdb.dbo.sysmanagement_shared_registered_servers_internal
"
$cmd4.Connection = $CMSServerConnection
$rowsInserted = $cmd4.ExecuteNonQuery()
# Create a Dataset to hold the DataTable from server_list
$dataSet = new-object "System.Data.DataSet" "ServerListDataSet"
$query = "SET NOCOUNT ON;"
$query = $query + "SELECT server_name "
$query = $query + "FROM $CMSDatabase.$CMSTable where server_name not in(
select server_name from $CMSDatabase.dbo.excludeServerList
)"
# Create a DataAdapter which you'll use to populate the DataSet with the results
$dataAdapter = new-object "System.Data.SqlClient.SqlDataAdapter" ($query, $CMSServerConnection)
$dataAdapter.Fill($dataSet) | Out-Null
$dataTable = new-object "System.Data.DataTable" "ServerList"
$dataTable = $dataSet.Tables[0]
# for each server
$dataTable | FOREACH-OBJECT {
Try
{ #write-host "server_name: " $_.server_name
log "server_name : $ServerBConnectionString" yellow
$ServerBConnectionString = "Data Source="+$_.server_name+";Initial Catalog=$SrcDatabase;User Id=$UserName;PWD=$Password"
#write-host "ServerBConnection: " $ServerBConnectionString
$ServerBConnection = new-object system.data.SqlClient.SqlConnection($ServerBConnectionString);
$ServerBConnection.Open()
# create SMO objects so that tables can be created and dropped
$srv = new-Object Microsoft.SqlServer.Management.Smo.Server($ServerBConnection)
$db = New-Object Microsoft.SqlServer.Management.Smo.Database
$db = $srv.Databases.Item($SrcDatabase)
# collect port number from server
$cmd3 = new-object System.Data.SQLClient.SQLCommand
$cmd3.CommandText = "
SELECT
@@SERVERNAME as servername,
cast(CONNECTIONPROPERTY('local_tcp_port') as int) AS port
INTO $SrcTable
"
$cmd3.Connection = $ServerBConnection
$rowsInserted = $cmd3.ExecuteNonQuery()
# get port number from table
$cmd2 = new-object System.Data.SQLClient.SQLCommand
$cmd2.CommandText = "SELECT port FROM $SrcTable"
$cmd2.Connection = $ServerBConnection
$port = [Int32]$cmd2.ExecuteScalar()
#write-host "port: " $port
log "port: $port" yellow
# update cms table
$cmd = new-object System.Data.SQLClient.SQLCommand
$cmd.CommandText = "UPDATE $CMSDatabase.$CMSTable SET server_port = $port WHERE server_name = '"+$_.server_name+"'"
#write-host "success: " $cmd.CommandText
$cmd.Connection = $CMSServerConnection
$rowsUpdated = $cmd.ExecuteNonQuery()
log "success: $_.server_name" green
#write-host "success: " $_.server_name
$ServerBConnection.Close()
} Catch [System.Exception]
{
$ex = $_.Exception
#write-host "failure: " $ex.Message " on server " $_.server_name
log "failure: $ex.Message on server $_.server_name" red
#Write-Host $ex.Message
}
Finally
{
#write-host "server_name: " $_.server_name
}
}
$CMSServerConnection.Close()
quelle
Ich habe dieses Problem auch speziell mit dem integrierten SQL Server-Job syspolicy_purge_history erlitten. Das Problem ist anscheinend mit SQLPS in SQL Server 2012 und höher. Ich habe festgestellt, dass 2008 R2 nicht das gleiche Problem hat.
SQL Server 2012 SQLPS wurde sicherer gemacht, indem eine explizite Einstellung der Prozessausführungsrichtlinie für SQLPS hinzugefügt wurde, die entfernt werden soll. Das Problem ist, dass der Ausführungsrichtlinienbereich für Powershell eine Hierarchie ist und das Ausführen einer
set-ExecutionPolicy
mit einer restriktiveren Richtlinie in einem niedrigeren Bereich (z. B. Prozess) einen Fehler wie den folgenden auslöst:Ihre Optionen sind also:
Für mich ist die frühere Registrierungsänderung einfacher, als den Domänenadministrator davon zu überzeugen, eine andere Computerrichtlinie nur für meine Server einzurichten.
quelle