Tengo la siguiente configuración de código en el paso de trabajo del Agente SQL que no se está ejecutando. El mensaje recibido es simplemente:
No se puede iniciar la ejecución del paso 1 (razón: línea (46): error de sintaxis). El paso falló.
La duración del trabajo es: 00:00:00
La línea 46 de este script es un here-string
:
,@DriveLetter = '$($c.DriveLetter)'
Este script se ejecuta perfecto fuera del Agente SQL Server.
Tabla ServerNames:
CREATE TABLE ServerTable (
ServerName varchar(50)
)
La tabla de espacio en disco sería algo similar a:
CREATE TABLE DiskSpace (
ID int IDENTITY(1,1),
ServerName varchar(50),
DriveLetter varchar(2),
DiskSpaceCapacityGB decimal(12,5),
DiskSpaceFreeGB decimal(12,5)
)
Script de PowerShell:
This command is to allow SQL Agent job to show failure in event PowerShell script errors
Default behavior in SQL Agent for PowerShell steps it 'Continue'
$erroractionpreference = "Stop"
$sqlInstance = 'server1'
$sqlDatabase = 'database1'
$qServerList = @"
Select ServerName From ServerTable
"@
$srvList = Invoke-Sqlcmd -ServerInstance $sqlInstance -Database $sqlDatabase -Query $qServerList |
Where-Object {$_ -ne '' -or $_ -ne $null} | Select-Object -ExpandProperty ServerName
foreach ($s in $srvList)
{
if (Test-Connection -ComputerName $s -Count 1 -ErrorAction 'SilentlyContinue')
{
try
{
$cServer = Get-WmiObject Win32_Volume -ComputerName $s -ErrorAction 'Stop' |
where {$.DriveType -eq 3 -and $.DriveLetter } |
Select-Object @{Label="ServerName";Expression={$s}},
@{Label="DriveLetter";Expression={$.DriveLetter}},
@{Label="DiskSpaceCapacityGB";Expression={"{0:N0}" -f($.Capacity/1GB)}},
@{Label="DiskFreeSpaceGB";Expression={"{0:N2}" -f($_.FreeSpace/1GB)}}
foreach ($c in $cServer)
{
$qAddServerDiskSpace = @"
EXEC [dbo].[StoredProcInsert]
@ServerName = '$($c.ServerName)'
,@DriveLetter = '$($c.DriveLetter)'
,@DiskSpaceCapacityGB = $($c.DiskSpaceCapacityGB)
,@DiskFreeSpaceGB = $($c.DiskFreeSpaceGB)
"@
try
{
Invoke-Sqlcmd -ServerInstance $sqlInstance -Database $sqlDatabase -Query $qAddServerDiskSpace -ErrorAction 'Stop'
}
catch
{
$ErrorMsg = $_.Exception.Message
$fullMsg = "Error writing executing dbo.StoredProcInsert for $s - $ErrorMsg"
Return $fullMsg
}
}
}
catch
{
$ErrorMsg = $_.Exception.Message
$qAddPSErrorLog = @"
EXEC [dbo].[StoredProcInsert_Error]
@ServerName = '$($cServer.ServerName)'
, @ErrorText = '$($ErrorMsg)'
"@
try
{
Invoke-Sqlcmd -ServerInstance $sqlInstance -Database $sqlDatabase -Query $qAddPSErrorLog -ErrorAction 'Stop'
}
catch
{
$ErrorMsg = $_.Exception.Message
$fullMsg = "Error writing executing dbo.StoredProcInsert_Error for $s - $ErrorMsg"
Return $fullMsg
}
}
}
else
{
$qAddPSErrorLog = @"
EXEC [dbo].[StoredProcInsert_Error]
@ServerName = '$($cServer.ServerName)'
, @ErrorText = 'Unable to ping server'
"@
try
{
Invoke-Sqlcmd -ServerInstance $sqlInstance -Database $sqlDatabase -Query $qAddPSErrorLog -ErrorAction 'Stop'
}
catch
{
$ErrorMsg = $_.Exception.Message
$fullMsg = "Error writing executing dbo.StoredProcInsert_Error for $s - $ErrorMsg"
Return $fullMsg
}
}
}
EDITAR
Configure pasos adicionales para intentar usar el tipo CmdExec como PowerShell -Command "& { }"
. Con esta ejecución, el script se ejecuta y el registro de errores se llena para los bloques catch apropiados, pero no se escriben datos de espacio en disco en la tabla.
El historial del agente para esta ejecución muestra un mensaje de advertencia:
Mensaje ejecutado como usuario: NT Service \ SQLAgent $ myInstance. ADVERTENCIA: Algunos nombres de comandos importados incluyen verbos no aprobados que pueden hacerlos menos reconocibles. Use el parámetro Verbose para obtener más detalles o escriba Get-Verb para ver la lista de verbos aprobados. Código de salida de proceso 0. El paso se realizó correctamente.
Si utilizo el mismo paso de tipo pero llamo al archivo: PowerShell -File MyScript.ps1
recibo el mismo mensaje que el paso de PowerShell del tipo anterior para el error de sintaxis.