【发布时间】:2015-05-11 23:46:03
【问题描述】:
当我使用以下命令从命令提示符手动执行它时,我有一个完美运行的 powershell 脚本:
powershell -NoLogo -NonInteractive -File "D:\ServerFolders\Company\Scripts\Powershell Scripts\SendMonthlyGrowthRateReport.ps1"
脚本正在打开一个 Excel 电子表格,从 SQL 中提取一些数据到电子表格中,保存一份带有当前日期的电子表格副本,然后通过 SQL sp_send_dbmail 将电子表格通过电子邮件发送出去。它还将当前状态记录到日志文件中。
现在我在 Windows 2012 R2 上设置了一个计划任务,每月执行一次上述命令,但是当我手动运行任务或尝试让它自行启动时,只生成日志文件,电子表格没有已保存且电子邮件永远不会消失。
有什么想法吗?
更新: 下面是脚本中的代码,我还要注意powershell在通过计划任务执行时返回退出代码0...
$DebugPreference = 2
$VerbosePreference = 2
$WarningPreference = 2
#param([string] $TemplateFilePath = "TemplateFilePath",
# [string]$StorageRoot = "StorageRoot",
# [string]$NameFormat = "NameFormat",
# [string]$ReportType = "ReportType",
# [string] $SendReportTo = "SendReportTo")
$TemplateFilePath = 'D:\ServerFolders\Company\Spreadsheets\templates\DatabaseGrowthTemplate.xlsx'
$StorageRoot = 'D:\ServerFolders\Company\Spreadsheets'
$NameFormat = '%type% Database Growth Report %date%.xlsx'
$ReportType = "Monthly"
$SendReportTo ="*******@someDomain.com"
$Date = get-Date
$LogFile = "D:\ServerFolders\Company\SyncLogs\MonthlyGrowthReport" + $Date.toString("yyyy-MM-dd hhmmss") + ".log"
Function LogWrite
{
Param ([string]$logstring)
$date = get-date
$DateString = $date.toString("yyyy-MM-dd hh:mm:ss")
$FileValue = $DateString +' - ' + $logstring
if($LogFile -ne $null -and $LogFile -ne "")
{
Add-content $Logfile -value $FileValue
}
Write-Host $FileValue
}
if ($ReportType -ne 'Weekly' -and $ReportType -ne 'Monthly' -and $ReportType -ne 'Quarterly' -and $ReportType -ne 'Yearly')
{
Write-Host "Valid options for ReportType parameter are 'Weekly', 'Monthly', 'Quarterly', or 'Yearly'"
exit
}
$Date = get-Date
$DateString = $Date.ToString("yyyy-MM-dd")
$FromDate = $DateString
$FileName = $NameFormat.Replace("%date%", $DateString)
$FileName = $FileName.Replace("%type%", $ReportType)
$Destination = join-path $StorageRoot $FileName
$LogWrite = "Generate Destination File of " + $Destination
LogWrite $LogWrite
$IncrementType ="Days"
if ($ReportType -eq "Weekly"){
$IncrementType = "Weeks"
}
if ($ReportType -eq "Monthly"){
$IncrementType = "Months"
}
if ($ReportType -eq "Quarterly"){
$IncrementType = "Quarters"
}
if ($ReportType -eq "Yearly") {
$IncrementType = "Years"
}
$IncrementBackValue = -1
## Connect to the target SQL Server and run the query to refresh data
$cstr = "Server=SERVERNAME\INSTANCENAME;Database=Logging;Trusted_Connection=True;"
$cn = new-object system.data.SqlClient.SqlConnection($cstr);
LogWrite "Connecting to SQL"
$cn.Open()
#Query the first date from using the built-in function
$dateQuery = "SELECT [dbo].[ufn_getIncrementBackDate]('$DateString', '${IncrementType}', ${IncrementBackValue}) as [StartDate]"
$cmd1 = New-Object System.Data.SqlClient.SqlCommand($dateQuery, $cn)
$DateDS = $cmd1.ExecuteReader();
while($DateDS.Read()){
$StartDate = $DateDS.GetDateTime(0)
}
$DateDS.Close()
#Copy isn't needed Open the template and then at the End do a save as
LogWrite "Opening Excel workbook..."
# Open the Excel document and pull in the 'Data' worksheet
$Excel = New-Object -Com Excel.Application
$Workbook = $Excel.Workbooks.Open($TemplateFilePath)
$page = 'Data'
$ws = $Workbook.worksheets | where-object {$_.Name -eq $page}
# Delete the current contents of the page
$ws.Cells.Clear() | Out-Null
LogWrite "Generating Report Data..."
#Prepare adapter objects for reading info into Excel
$ds = new-object "System.Data.DataSet" "dsProductData"
$q = "usp_GenerateDatabaseSizeReport @FirstDate='$StartDate'"
$da = new-object "System.Data.SqlClient.SqlDataAdapter" ($q, $cn)
$da.Fill($ds) | Out-Null
$dtProduct = $ds.Tables[0]
# Set variables for the worksheet cells, and for navigation
$cells=$ws.Cells
$row=1
$col=1
$MaxCol = 1
$MaxRow = 1
LogWrite "Populating Data worksheet.."
#Fill Headers
foreach($column in $dtProduct.Columns){
$cells.item($row, $col) = $column.ColumnName
if ($col -gt $MaxCol){
$MaxCol = $col
}
$col++
}
# Add the results from the DataTable object to the worksheet
foreach($dataRow in $dtProduct){
$row++
$col = 1
foreach($column in $dtProduct.Columns)
{
if ($col -eq 1){
$cells.item($row, $col) = $dataRow[$column.ColumnName].ToString()
} else {
$cells.item($row, $col) = $dataRow[$column.ColumnName].ToString()
}
$col++
}
if ($row -gt $MaxRow){
$MaxRow = $row
}
}
LogWrite "Finished populating Data..."
# Set the width of the columns automatically
$ws.columns.item("A:Z").EntireColumn.AutoFit() | out-null
#Format Date Column
$ws.Range("A2:A1000").NumberFormat ="m/d/yyyy"
#Create the Line Chart's
$ColumnLetter = "A"
if ($MaxCol -eq 1) { $ColumnLetter = "A" }
if ($MaxCol -eq 2) { $ColumnLetter = "B" }
if ($MaxCol -eq 3) { $ColumnLetter = "C" }
if ($MaxCol -eq 4) { $ColumnLetter = "D" }
if ($MaxCol -eq 5) { $ColumnLetter = "E" }
if ($MaxCol -eq 6) { $ColumnLetter = "F" }
if ($MaxCol -eq 7) { $ColumnLetter = "G" }
if ($MaxCol -eq 8) { $ColumnLetter = "H" }
if ($MaxCol -eq 9) { $ColumnLetter = "I" }
if ($MaxCol -eq 10) { $ColumnLetter = "J" }
if ($MaxCol -eq 11) { $ColumnLetter = "K" }
if ($MaxCol -eq 12) { $ColumnLetter = "L" }
if ($MaxCol -eq 13) { $ColumnLetter = "M" }
if ($MaxCol -eq 14) { $ColumnLetter = "N" }
if ($MaxCol -eq 15) { $ColumnLetter = "O" }
if ($MaxCol -eq 16) { $ColumnLetter = "P" }
if ($MaxCol -eq 17) { $ColumnLetter = "Q" }
if ($MaxCol -eq 18) { $ColumnLetter = "R" }
if ($MaxCol -eq 19) { $ColumnLetter = "S" }
if ($MaxCol -eq 20) { $ColumnLetter = "T" }
if ($MaxCol -eq 21) { $ColumnLetter = "U" }
if ($MaxCol -eq 22) { $ColumnLetter = "V" }
if ($MaxCol -eq 23) { $ColumnLetter = "W" }
if ($MaxCol -eq 24) { $ColumnLetter = "X" }
if ($MaxCol -eq 25) { $ColumnLetter = "Y" }
if ($MaxCol -eq 26) { $ColumnLetter = "Z" }
$RangeString = "A1:"+$ColumnLetter
#$RangeString
$RangeString =$RangeString + $MaxRow
#$RangeString
$range = $ws.range($RangeString)
LogWrite "Performing Chart updates."
$page = "Chart"
$ws = $Workbook.worksheets | where-object {$_.Name -eq $page}
foreach($Shape in $ws.Shapes){
if ($Shape.HasChart){
$chart = $Shape.Chart
break
}
if ($chart -ieq $null){
Write-Host "Can't find chart!!!"
} else {
$chart.SetSourceData($range)
}
LogWrite "Saving updated copy of Excel workbook."
# Close the workbook and exit Excel
$Workbook.SaveAs($Destination)
$workbook.Close($true)
$excel.quit()
$DestinationFileO = New-Object System.IO.FileInfo($Destination)
$EmailSubject = $DestinationFileO.Name.Replace($DestinationFileO.Extension, "")
LogWrite "Sending Excel Workbook via email."
#Send an email to operator with report
$SendEmailCmdText ="exec msdb..sp_send_dbmail @profile_name='GMail'
, @recipients = '${SendReportTo}'
, @subject = '${EmailSubject}'
, @body = 'Attached is the $EmailSubject for database server [HOMEGROWNSERVER\TFSSQL].'
, @file_attachments = '${Destination}'
--, @query_result_header = 1
--, @query_result_separator=','
--, @query_result_width = 32767
--, @append_query_error = 1
--, @query_result_no_padding = 1"
$cmd2 = New-Object System.Data.SqlClient.SqlCommand($SendEmailCmdText, $cn)
$cmd2.ExecuteNonQuery()
$cn.Close()
LogWrite "Process Complete"
【问题讨论】:
-
这可能是凭据问题,您在计划任务中设置了哪个帐户?和手动执行脚本的一样吗?
-
我正在使用与测试脚本相同的“管理员”帐户来执行计划任务,并选择了“无论用户是否登录都运行”,任务已配置为“Windows 7, Windows Server 2008 R2”虽然我尝试了其他“配置”选项但没有成功
-
下一个猜测是自动任务运行时没有映射 D: 驱动器。
-
D 是一个物理驱动器。它在那里,也是写入日志文件的地方。
-
您是否尝试选中“以最高权限运行”框?
标签: windows powershell scheduled-tasks export-to-excel windows2012