我如何使用PowerShell自动化SQL查询和创buildExcel文件?

我有一个XML文件,我们的实践pipe理软件(PMS)用来查询其MS SQL数据库,并创build和Excel报告的结果。 不幸的是,PMS没有能力定期将其作为自动化的任务,他们已经表示超出了他们的支持范围。

XML文件的设置如下所示:

<?xml version="1.0" encoding="utf-8"?> <reports> <parameters> </parameters> <report name="Individuals" includeHeader="true"><![CDATA[ SELECT DISTINCT [cases].[name] as MatterName, [cases].[reference] as MatterNumber, [cases].[category] as MatterType, DATEADD(D, [cases].[modified] / 864000000000, DATEADD(MS, ([cases].[modified] % 864000000000) / 10000, DATEADD(NS, ([cases].[modified] % 10000) * 100, convert(datetime2, '0001-01-01')))) as LastChanged, [dd_client].[clientname] as ClientName, [dd_entity_d2].[email] as ClientEmail, [dd_entity_d4].[firstname] as PartyFirstName, [dd_entity_d4].[lastname] as PartyLastName, [dd_entity_d4].[email] as PartyEmail, [dd_entity_d4].id as PartyEntityID, [cases].[id] as primarykeycolumn, etResponsible.[PreferredName] ResponsiblePerson, etActing.[PreferredName] ActingPerson, etAssissting.[PreferredName] AssisstingPerson FROM PracticeEvolve_doc.dbo.[cases] INNER JOIN PracticeEvolve_c1.dbo.DocumaticsMap dm on dm.DocumaticsID = [cases].ID and dm.Entitytype = 'Matter' INNER JOIN PracticeEvolve_c1.dbo.[Matter] mt on mt.Matterid = dm.ClickOneID LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emResponsible on emResponsible.MatterID = mt.MatterID and emResponsible.AssociationTypeID = 13 LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emActing on emActing.MatterID = mt.MatterID and emActing.AssociationTypeID = 15 LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emAssissting on emAssissting.MatterID = mt.MatterID and emAssissting.AssociationTypeID = 16 LEFT JOIN PracticeEvolve_c1.dbo.Employee eResponsible on eResponsible.EmployeeID = emResponsible.EmployeeID LEFT JOIN PracticeEvolve_c1.dbo.Employee eActing on eActing.EmployeeID = emActing.EmployeeID LEFT JOIN PracticeEvolve_c1.dbo.Employee eAssissting on eAssissting.EmployeeID = emAssissting.EmployeeID LEFT JOIN PracticeEvolve_c1.dbo.Entity etResponsible on etResponsible.EntityID = eResponsible.EntityID LEFT JOIN PracticeEvolve_c1.dbo.Entity etActing on etActing.EntityID = eActing.EntityID LEFT JOIN PracticeEvolve_c1.dbo.Entity etAssissting on etAssissting.EntityID = eAssissting.EntityID LEFT JOIN PracticeEvolve_doc.dbo.[dd_client] ON [dd_client].[id]=[cases].[clientid] LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d2] ON [dd_manytomanydd_entity_d2].[fkid] = [dd_client].[fk_entities] LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d2] ON [dd_entity_d2].[id] = [dd_manytomanydd_entity_d2].[pkid] LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_party_d3] ON [dd_manytomanydd_party_d3].[fkid] = [dd_entity_d2].[fk_parties] LEFT JOIN PracticeEvolve_doc.dbo.[dd_party] as [dd_party_d3] ON [dd_party_d3].[id] = [dd_manytomanydd_party_d3].[pkid] LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d4] ON [dd_manytomanydd_entity_d4].[fkid] = [dd_party_d3].[fk_entity] LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d4] ON [dd_entity_d4].[id] = [dd_manytomanydd_entity_d4].[pkid] WHERE ([cases].[deleted]=0 AND [dd_entity_d2].[type] = 'Individual' AND ([cases].[modified] >= 635715648000000000 AND [cases].[modified] > 599266080000000000)) ]]></report> <report name="Joint Parties" includeHeader="true"><![CDATA[ SELECT DISTINCT [cases].[name] as MatterName, [cases].[reference] as MatterNumber, [cases].[category] as MatterType, DATEADD(D, [cases].[modified] / 864000000000, DATEADD(MS, ([cases].[modified] % 864000000000) / 10000, DATEADD(NS, ([cases].[modified] % 10000) * 100, convert(datetime2, '0001-01-01')))) as LastChanged, [dd_client].[clientname] as ClientName, [dd_entity_d2].[email] as ClientEmail, [dd_entity_d4].[firstname] as PartyFirstName, [dd_entity_d4].[lastname] as PartyLastName, [dd_entity_d4].[email] as PartyEmail, [dd_entity_d4].id as PartyEntityID, [cases].[id] as primarykeycolumn, etResponsible.[PreferredName] ResponsiblePerson, etActing.[PreferredName] ActingPerson, etAssissting.[PreferredName] AssisstingPerson FROM PracticeEvolve_doc.dbo.[cases] INNER JOIN PracticeEvolve_c1.dbo.DocumaticsMap dm on dm.DocumaticsID = [cases].ID and dm.Entitytype = 'Matter' INNER JOIN PracticeEvolve_c1.dbo.[Matter] mt on mt.Matterid = dm.ClickOneID LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emResponsible on emResponsible.MatterID = mt.MatterID and emResponsible.AssociationTypeID = 13 LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emActing on emActing.MatterID = mt.MatterID and emActing.AssociationTypeID = 15 LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emAssissting on emAssissting.MatterID = mt.MatterID and emAssissting.AssociationTypeID = 16 LEFT JOIN PracticeEvolve_c1.dbo.Employee eResponsible on eResponsible.EmployeeID = emResponsible.EmployeeID LEFT JOIN PracticeEvolve_c1.dbo.Employee eActing on eActing.EmployeeID = emActing.EmployeeID LEFT JOIN PracticeEvolve_c1.dbo.Employee eAssissting on eAssissting.EmployeeID = emAssissting.EmployeeID LEFT JOIN PracticeEvolve_c1.dbo.Entity etResponsible on etResponsible.EntityID = eResponsible.EntityID LEFT JOIN PracticeEvolve_c1.dbo.Entity etActing on etActing.EntityID = eActing.EntityID LEFT JOIN PracticeEvolve_c1.dbo.Entity etAssissting on etAssissting.EntityID = eAssissting.EntityID LEFT JOIN PracticeEvolve_doc.dbo.[dd_client] ON [dd_client].[id]=[cases].[clientid] LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d2] ON [dd_manytomanydd_entity_d2].[fkid] = [dd_client].[fk_entities] LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d2] ON [dd_entity_d2].[id] = [dd_manytomanydd_entity_d2].[pkid] LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_party_d3] ON [dd_manytomanydd_party_d3].[fkid] = [dd_entity_d2].[fk_parties] LEFT JOIN PracticeEvolve_doc.dbo.[dd_party] as [dd_party_d3] ON [dd_party_d3].[id] = [dd_manytomanydd_party_d3].[pkid] LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d4] ON [dd_manytomanydd_entity_d4].[fkid] = [dd_party_d3].[fk_entity] LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d4] ON [dd_entity_d4].[id] = [dd_manytomanydd_entity_d4].[pkid] WHERE ([cases].[deleted]=0 AND [dd_entity_d2].[type] = 'Joint Party' AND ([cases].[modified] >= 635715648000000000 AND [cases].[modified] > 599266080000000000)) ]]></report> <report name="Organisation" includeHeader="true"><![CDATA[ SELECT DISTINCT [cases].[name] as MatterName, [cases].[reference] as MatterNumber, [cases].[category] as MatterType, DATEADD(D, [cases].[modified] / 864000000000, DATEADD(MS, ([cases].[modified] % 864000000000) / 10000, DATEADD(NS, ([cases].[modified] % 10000) * 100, convert(datetime2, '0001-01-01')))) as LastChanged, [dd_client].[clientname] as ClientName, [dd_entity_d2].[email] as ClientEmail, [dd_entity_d4].[firstname] as PartyFirstName, [dd_entity_d4].[lastname] as PartyLastName, [dd_entity_d4].[email] as PartyEmail, [dd_entity_d4].id as PartyEntityID, [cases].[id] as primarykeycolumn, etResponsible.[PreferredName] ResponsiblePerson, etActing.[PreferredName] ActingPerson, etAssissting.[PreferredName] AssisstingPerson FROM PracticeEvolve_doc.dbo.[cases] INNER JOIN PracticeEvolve_c1.dbo.DocumaticsMap dm on dm.DocumaticsID = [cases].ID and dm.Entitytype = 'Matter' INNER JOIN PracticeEvolve_c1.dbo.[Matter] mt on mt.Matterid = dm.ClickOneID LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emResponsible on emResponsible.MatterID = mt.MatterID and emResponsible.AssociationTypeID = 13 LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emActing on emActing.MatterID = mt.MatterID and emActing.AssociationTypeID = 15 LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emAssissting on emAssissting.MatterID = mt.MatterID and emAssissting.AssociationTypeID = 16 LEFT JOIN PracticeEvolve_c1.dbo.Employee eResponsible on eResponsible.EmployeeID = emResponsible.EmployeeID LEFT JOIN PracticeEvolve_c1.dbo.Employee eActing on eActing.EmployeeID = emActing.EmployeeID LEFT JOIN PracticeEvolve_c1.dbo.Employee eAssissting on eAssissting.EmployeeID = emAssissting.EmployeeID LEFT JOIN PracticeEvolve_c1.dbo.Entity etResponsible on etResponsible.EntityID = eResponsible.EntityID LEFT JOIN PracticeEvolve_c1.dbo.Entity etActing on etActing.EntityID = eActing.EntityID LEFT JOIN PracticeEvolve_c1.dbo.Entity etAssissting on etAssissting.EntityID = eAssissting.EntityID LEFT JOIN PracticeEvolve_doc.dbo.[dd_client] ON [dd_client].[id]=[cases].[clientid] LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d2] ON [dd_manytomanydd_entity_d2].[fkid] = [dd_client].[fk_entities] LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d2] ON [dd_entity_d2].[id] = [dd_manytomanydd_entity_d2].[pkid] LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_party_d3] ON [dd_manytomanydd_party_d3].[fkid] = [dd_entity_d2].[fk_parties] LEFT JOIN PracticeEvolve_doc.dbo.[dd_party] as [dd_party_d3] ON [dd_party_d3].[id] = [dd_manytomanydd_party_d3].[pkid] LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d4] ON [dd_manytomanydd_entity_d4].[fkid] = [dd_party_d3].[fk_entity] LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d4] ON [dd_entity_d4].[id] = [dd_manytomanydd_entity_d4].[pkid] WHERE ([cases].[deleted]=0 AND [dd_entity_d2].[type] = 'Organisation' AND ([cases].[modified] >= 635715648000000000 AND [cases].[modified] > 599266080000000000)) ]]></report> </reports> 

而这个file upload到我们的PMS,混淆(出于某种原因),然后运行。 Excel必须在当时开放,并在运行时创build一个包含三个工作表(个人,联合组织和组织)的工作簿。 这个输出是完美的!

在这里输入图像说明

现在我需要以某种方式自动化它,以便它可以定期运行而无需用户干预,并将输出发送到电子邮件地址或转储到云存储文件夹。

这个XML文件中的三个SQL查询可以单独运行,也可以在MSMSQLMS中一起运行,并将正确的信息输出到“网格”视图 – 我testing过了 – 所以我正在研究使用PowerShell运行查询,然后使用Windows任务自动化调度程序,但我的知识PS和MSSQL是有限的。
到目前为止,我读到的内容显示输出为CSV或TXT(我们将不得不使用pipe道分隔符,因为某些客户端名称带有逗号),但就向公司发送报告而言,这不是一个非常干净的输出导演去…我真的希望有输出格式与XML文件格式相同的方式。

如果我们的PMS报告function是Excel输出的devise者,也许这是不可能的。

任何人都可以帮忙吗?

提前致谢。 PS。 很抱歉,这个post太长了

更多的谷歌和咖啡更新后

我在GitHub上find了一个PS模块,我将其添加到PS脚本中。 我努力让它在没有提升权限的情况下运行,所以我也用Googlesearch了如何build立自我提升。

这是我到目前为止,它的工作原理! 它创build3个独立的Excel文件。

 # Get the ID and security principal of the current user account $myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent() $myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID) # Get the security principal for the Administrator role $adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator # Check to see if we are currently running "as Administrator" if ($myWindowsPrincipal.IsInRole($adminRole)) { # We are running "as Administrator" - so change the title and background color to indicate this $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)" $Host.UI.RawUI.BackgroundColor = "DarkBlue" clear-host } else { # We are not running "as Administrator" - so relaunch as administrator # Create a new process object that starts PowerShell $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell"; # Specify the current script path and name as a parameter $newProcess.Arguments = $myInvocation.MyCommand.Definition; # Indicate that the process should be elevated $newProcess.Verb = "runas"; # Start the new process [System.Diagnostics.Process]::Start($newProcess); # Exit from the current, unelevated, process exit } # Import PSExcel module Import-Module C:\scripts-and-reports\Modules\PSExcel # Import SQLPS module Import-Module sqlps # Create individuals.xlsx invoke-sqlcmd -inputfile "C:\scripts-and-reports\individuals.sql" -serverinstance "PE-SERVER\PRACTICEEVOLVE" -database "PracticeEvolve_doc" | Export-XLSX -Path C:\scripts-and-reports\individuals.xlsx # Create joint-parties.xlsx invoke-sqlcmd -inputfile "C:\scripts-and-reports\joint-parties.sql" -serverinstance "PE-SERVER\PRACTICEEVOLVE" -database "PracticeEvolve_doc" | Export-XLSX -Path C:\scripts-and-reports\joint-parties.xlsx # Create organisations.xlsx invoke-sqlcmd -inputfile "C:\scripts-and-reports\organisations.sql" -serverinstance "PE-SERVER\PRACTICEEVOLVE" -database "PracticeEvolve_doc" | Export-XLSX -Path C:\scripts-and-reports\organisations.xlsx Write-Host -NoNewLine "Export and report creation complete! Press any key to continue..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") 

我认为可以使用batch file现在调用这个.ps1文件,并在Windows任务计划程序中安排。 我可能甚至可以使用blat.exe发送一封电子邮件,其中包含转储到云存储文件夹的报告的链接。 我可以压缩包并放置在每个服务器上以实现自动化的一次性设置。

我想要做的就是将三个工作表合并到同一个工作簿中的每个工作表中,并在名称前面加上date。 'yyyy-mm-dd_Office-Name.xlsx',如果可能的话,添加一些格式来接近我在截图中的内容。

任何帮助在这里节省我几个小时的论坛淘宝?

干杯

肯定可以。

在Excel中转​​到数据。

在这里输入图像说明 select从SQL Server

您将需要inputSQL Server的地址

点击确定? 然后你应该被提出这个观点。 在这里输入图像说明 select您要连接的表格。

在这里输入图像说明 一旦你select,你将会进入结束屏幕。

点击完成

在这里输入图像说明

一旦你看到上面的视图命中属性,这是你可以自定义你的查询。

在下面将Command Type更改为SQL并粘贴到您的查询中。

一旦完成select好,刚刚完成,它应该导入你的数据集。 在这里输入图像说明 为了进一步刷新,在“全部刷新”button旁边的“数据”权限下有一个“连接”,可以刷新它。 希望这有助于队友。