From 490196cc1e8772a205b46463a25dfdb4c665146f Mon Sep 17 00:00:00 2001 From: Chrissy LeMaire Date: Tue, 28 May 2019 19:46:12 +0000 Subject: [PATCH] Export Add Append and other Fixes (#5627) * not done yet test with Export-DbaInstance -SqlInstance sql2017 * lets see what fails * pupdates * phfewf * fixes * update test * fix some things * fixed dat * remove time consuming test * this is problematic * add things * add progress, still needs work * lil fixes * pupdate * finally * fix that * formatting * fixed * finally --- functions/Export-DbaAvailabilityGroup.ps1 | 169 ------ functions/Export-DbaCredential.ps1 | 33 +- functions/Export-DbaDacPackage.ps1 | 61 +-- functions/Export-DbaDbTableData.ps1 | 7 +- functions/Export-DbaDiagnosticQuery.ps1 | 39 +- functions/Export-DbaExecutionPlan.ps1 | 23 +- functions/Export-DbaInstance.ps1 | 88 ++-- functions/Export-DbaLinkedServer.ps1 | 22 +- functions/Export-DbaLogin.ps1 | 34 +- .../Export-DbaPfDataCollectorSetTemplate.ps1 | 31 +- functions/Export-DbaRegServer.ps1 | 43 +- functions/Export-DbaRepServerSetting.ps1 | 46 +- functions/Export-DbaScript.ps1 | 43 +- functions/Export-DbaSpConfigure.ps1 | 51 +- functions/Export-DbaUser.ps1 | 495 ++++++++---------- functions/Export-DbaXECsv.ps1 | 29 +- functions/Export-DbaXESessionTemplate.ps1 | 24 +- internal/functions/Get-ExportFIlePath.ps1 | 44 ++ internal/functions/Test-ExportDirectory.ps1 | 10 + tests/Export-DbaAvailabilityGroup.Tests.ps1 | 78 --- tests/Export-DbaCredential.Tests.ps1 | 91 +++- tests/Export-DbaDacPackage.Tests.ps1 | 6 +- tests/Export-DbaDbTableData.Tests.ps1 | 2 +- tests/Export-DbaDiagnosticQuery.Tests.ps1 | 7 +- tests/Export-DbaExecutionPlan.Tests.ps1 | 2 +- tests/Export-DbaInstance.Tests.ps1 | 16 +- tests/Export-DbaLinkedServer.Tests.ps1 | 2 +- tests/Export-DbaLogin.Tests.ps1 | 17 +- ...rt-DbaPfDataCollectorSetTemplate.Tests.ps1 | 2 +- tests/Export-DbaRegServer.Tests.ps1 | 2 +- tests/Export-DbaRepServerSetting.Tests.ps1 | 2 +- tests/Export-DbaScript.Tests.ps1 | 2 +- tests/Export-DbaSpConfigure.Tests.ps1 | 2 +- tests/Export-DbaUser.Tests.ps1 | 6 +- tests/Export-DbaXECsv.Tests.ps1 | 2 +- tests/Export-DbaXESessionTemplate.Tests.ps1 | 2 +- 36 files changed, 684 insertions(+), 849 deletions(-) delete mode 100644 functions/Export-DbaAvailabilityGroup.ps1 create mode 100644 internal/functions/Get-ExportFIlePath.ps1 create mode 100644 internal/functions/Test-ExportDirectory.ps1 delete mode 100644 tests/Export-DbaAvailabilityGroup.Tests.ps1 diff --git a/functions/Export-DbaAvailabilityGroup.ps1 b/functions/Export-DbaAvailabilityGroup.ps1 deleted file mode 100644 index 13ee0c455a..0000000000 --- a/functions/Export-DbaAvailabilityGroup.ps1 +++ /dev/null @@ -1,169 +0,0 @@ -function Export-DbaAvailabilityGroup { - <# - .SYNOPSIS - Exports SQL Server Availability Groups to a T-SQL file. - - .DESCRIPTION - Exports SQL Server Availability Groups creation scripts to a T-SQL file. This is a function that is not available in SSMS. - - .PARAMETER SqlInstance - The target SQL Server instance or instances. SQL Server 2012 and above supported. - - .PARAMETER SqlCredential - Login to the target instance using alternative credentials. Windows and SQL Authentication supported. Accepts credential objects (Get-Credential) - - .PARAMETER Path - The directory name where the output files will be written. A sub directory with the format 'ServerName$InstanceName' will be created. A T-SQL scripts named 'AGName.sql' will be created under this subdirectory for each scripted Availability Group. - - .PARAMETER AvailabilityGroup - The Availability Group(s) to export - this list is auto-populated from the server. If unspecified, all logins will be processed. - - .PARAMETER ExcludeAvailabilityGroup - The Availability Group(s) to exclude - this list is auto-populated from the server. - - .PARAMETER NoClobber - Do not overwrite existing export files. - - .PARAMETER WhatIf - Shows you what it'd output if you were to run the command - - .PARAMETER Confirm - Confirms each step/line of output - - .PARAMETER EnableException - By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message. - This avoids overwhelming you with "sea of red" exceptions, but is inconvenient because it basically disables advanced scripting. - Using this switch turns this "nice by default" feature off and enables you to catch exceptions with your own try/catch. - - .NOTES - Tags: Hadr, HA, AG, AvailabilityGroup - Author: Chris Sommer (@cjsommer), cjsommer.com - - dbatools PowerShell module (https://dbatools.io) - Copyright: (c) 2018 by dbatools, licensed under MIT - License: MIT https://opensource.org/licenses/MIT - - .LINK - https://dbatools.io/Export-DbaAvailabilityGroup - - .EXAMPLE - PS C:\> Export-DbaAvailabilityGroup -SqlInstance sql2012 - - Exports all Availability Groups from SQL server "sql2012". Output scripts are written to the Documents\SqlAgExports directory by default. - - .EXAMPLE - PS C:\> Export-DbaAvailabilityGroup -SqlInstance sql2012 -Path C:\temp\availability_group_exports - - Exports all Availability Groups from SQL server "sql2012". Output scripts are written to the C:\temp\availability_group_exports directory. - - .EXAMPLE - PS C:\> Export-DbaAvailabilityGroup -SqlInstance sql2012 -Path 'C:\dir with spaces\availability_group_exports' -AvailabilityGroup AG1,AG2 - - Exports Availability Groups AG1 and AG2 from SQL server "sql2012". Output scripts are written to the C:\dir with spaces\availability_group_exports directory. - - .EXAMPLE - PS C:\> Export-DbaAvailabilityGroup -SqlInstance sql2014 -Path C:\temp\availability_group_exports -NoClobber - - Exports all Availability Groups from SQL server "sql2014". Output scripts are written to the C:\temp\availability_group_exports directory. If the export file already exists it will not be overwritten. - - #> - [CmdletBinding(SupportsShouldProcess)] - param ( - [parameter(Mandatory, ValueFromPipeline)] - [DbaInstanceParameter[]]$SqlInstance, - [PSCredential]$SqlCredential, - [object[]]$AvailabilityGroup, - [object[]]$ExcludeAvailabilityGroup, - [Alias("OutputLocation", "FilePath")] - [string]$Path = (Join-DbaPath -path (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport') -child "SqlAgExport"), - [switch]$NoClobber, - [switch]$EnableException - ) - - process { - foreach ($instance in $SqlInstance) { - try { - $server = Connect-SqlInstance -SqlInstance $instance -SqlCredential $SqlCredential - } catch { - Stop-Function -Message "Error occurred while establishing connection to $instance" -Category ConnectionError -ErrorRecord $_ -Target $instance -Continue - } - - if ($server.IsHadrEnabled -eq $false) { - Stop-Function -Message "Hadr is not enabled on this instance" -Continue - } else { - # Get all of the Availability Groups and filter if required - $ags = $server.AvailabilityGroups - } - - if (Test-Bound 'AvailabilityGroup') { - $ags = $ags | Where-Object Name -In $AvailabilityGroup - } - if (Test-Bound 'ExcludeAvailabilityGroup') { - $ags = $ags | Where-Object Name -NotIn $ExcludeAvailabilityGroup - } - - if ($ags) { - - # Set and create the OutputLocation if it doesn't exist - $sqlinst = $instance.ToString().Replace('\', '$') - $outputLocation = Join-DbaPath -Path $Path -child $sqlinst - - if (!(Test-Path $outputLocation -PathType Container)) { - $null = New-Item -Path $outputLocation -ItemType Directory -Force - } - - # Script each Availability Group - foreach ($ag in $ags) { - $agName = $ag.Name - - # Set the outfile name - if ($AppendDateToOutputFilename.IsPresent) { - $formatteddate = (Get-Date -Format 'yyyyMMdd_hhmm') - $outFile = Join-DbaPath -Path $outputLocation -Child "${AGname}_${formatteddate}.sql" - } else { - $outFile = Join-DbaPath -Path $outputLocation -Child "$agName.sql" - } - - # Check NoClobber and script out the AG - if ($NoClobber.IsPresent -and (Test-Path -Path $outFile -PathType Leaf)) { - Write-Message -Level Warning -Message "OutputFile $outFile already exists. Skipping due to -NoClobber parameter" - } else { - Write-Message -Level Verbose -Message "Scripting Availability Group [$agName] on $instance to $outFile" - - # Create comment block header for AG script - "/*" | Out-File -FilePath $outFile -Encoding ASCII -Force - " * Created by dbatools 'Export-DbaAvailabilityGroup' cmdlet on '$(Get-Date)'" | Out-File -FilePath $outFile -Encoding ASCII -Append - " * See https://dbatools.io/Export-DbaAvailabilityGroup for more help" | Out-File -FilePath $outFile -Encoding ASCII -Append - - # Output AG and listener names - " *" | Out-File -FilePath $outFile -Encoding ASCII -Append - " * Availability Group Name: $($ag.name)" | Out-File -FilePath $outFile -Encoding ASCII -Append - $ag.AvailabilityGroupListeners | ForEach-Object { " * Listener Name: $($_.name)" } | Out-File -FilePath $outFile -Encoding ASCII -Append - - # Output all replicas - " *" | Out-File -FilePath $outFile -Encoding ASCII -Append - $ag.AvailabilityReplicas | ForEach-Object { " * Replica: $($_.name)" } | Out-File -FilePath $outFile -Encoding ASCII -Append - - # Output all databases - " *" | Out-File -FilePath $outFile -Encoding ASCII -Append - $ag.AvailabilityDatabases | ForEach-Object { " * Database: $($_.name)" } | Out-File -FilePath $outFile -Encoding ASCII -Append - - # $ag | Select-Object -Property * | Out-File -FilePath $outFile -Encoding ASCII -Append - - "*/" | Out-File -FilePath $outFile -Encoding ASCII -Append - - # Script the AG - try { - $ag.Script() | Out-File -FilePath $outFile -Encoding ASCII -Append - Get-ChildItem $outFile - } catch { - Stop-Function -ErrorRecord $_ -Message "Error scripting out the availability groups. This is likely due to a bug in SMO." -Continue - } - } - } - } else { - Write-Message -Level Output -Message "No Availability Groups detected on $instance" - } - } - } -} \ No newline at end of file diff --git a/functions/Export-DbaCredential.ps1 b/functions/Export-DbaCredential.ps1 index 5593ac7f36..7fad738ce3 100644 --- a/functions/Export-DbaCredential.ps1 +++ b/functions/Export-DbaCredential.ps1 @@ -18,7 +18,10 @@ function Export-DbaCredential { Login to the target OS using alternative credentials. Accepts credential objects (Get-Credential) .PARAMETER Path - The path to the exported sql file. + The path to the directory that will contain the exported sql file. + + .PARAMETER FilePath + The specific path to a file which will contain the output. .PARAMETER Identity The credentials to export. If unspecified, all credentials will be exported. @@ -58,6 +61,8 @@ function Export-DbaCredential { [PSCredential]$SqlCredential, [PSCredential]$Credential, [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [switch]$ExcludePassword, [switch]$Append, [Parameter(ValueFromPipeline)] @@ -65,11 +70,14 @@ function Export-DbaCredential { [switch]$EnableException ) begin { + $null = Test-ExportDirectory -Path $Path $serverArray = @() $credentialArray = @{} $credentialCollection = New-Object System.Collections.ArrayList } process { + if (Test-FunctionInterrupt) { return } + if (-not $InputObject -and -not $SqlInstance) { Stop-Function -Message "You must pipe in a Credential or specify a SqlInstance" return @@ -114,7 +122,7 @@ function Export-DbaCredential { $creds | Add-Member -MemberType NoteProperty -Name 'ExcludePassword' -Value $ExcludePassword $credentialCollection.Add($credObject) | Out-Null } else { - if (!(Test-SqlSa -SqlInstance $server)) { + if (-not (Test-SqlSa -SqlInstance $server)) { Stop-Function -Message "Not a sysadmin on $instance. Quitting." -Target $instance -Continue } @@ -147,8 +155,6 @@ function Export-DbaCredential { $key = $input.Parent.Name + '::[' + $input.Name + ']' $credentialArray.add( $key, $true ) } - $timenow = (Get-Date -uformat "%m%d%Y%H%M%S") - $path = Join-DbaPath -Path $Path -Child "$($server.name.replace('\', '$'))-$timenow-credential.sql" } } @@ -156,14 +162,10 @@ function Export-DbaCredential { $sql = @() foreach ($cred in $credentialCollection) { Write-Message -Level Verbose -Message "Credentials in object = $($cred.Count)" - if (-not (Test-Bound -ParameterName Path)) { - $time = (Get-Date -Format yyyMMddHHmmss) - $mydocs = [Environment]::GetFolderPath('MyDocuments') - $serverName = $($cred[0].SqlInstance.replace('\', '$')) - $path = Join-DbaPath -Path $mydocs "$serverName-$time-credential.sql" - } foreach ($currentCred in $creds) { + $FilePath = Get-ExportFilePath -Path $PSBoundParameters.Path -FilePath $PSBoundParameters.FilePath -ServerName $currentCred.SqlInstance -Type Sql + $key = $currentCred.SqlInstance + '::' + $currentCred.Name if ( $credentialArray.ContainsKey($key) ) { $name = $currentCred.Name.Replace("'", "''") @@ -181,16 +183,15 @@ function Export-DbaCredential { try { if ($Append) { - Add-Content -Path $path -Value $sql + Add-Content -Path $FilePath -Value $sql } else { - Set-Content -Path $path -Value $sql + Set-Content -Path $FilePath -Value $sql } } catch { - Stop-Function -Message "Can't write to $path" -ErrorRecord $_ -Continue + Stop-Function -Message "Can't write to $FilePath" -ErrorRecord $_ -Continue } - - Write-Message -Level Verbose -Message "Credentials exported to $path" + Get-ChildItem -Path $FilePath + Write-Message -Level Verbose -Message "Credentials exported to $FilePath" } } - } \ No newline at end of file diff --git a/functions/Export-DbaDacPackage.ps1 b/functions/Export-DbaDacPackage.ps1 index 1eb8d6094c..b0613662ff 100644 --- a/functions/Export-DbaDacPackage.ps1 +++ b/functions/Export-DbaDacPackage.ps1 @@ -17,7 +17,10 @@ function Export-DbaDacPackage { Allows you to login to servers using alternative logins instead Integrated, accepts Credential object created by Get-Credential .PARAMETER Path - The directory where the .dacpac files will be exported to. Defaults to documents. + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER Database The database(s) to process - this list is auto-populated from the server. If unspecified, all databases will be processed. @@ -94,6 +97,8 @@ function Export-DbaDacPackage { [object[]]$ExcludeDatabase, [switch]$AllUserDatabases, [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [parameter(ParameterSetName = 'SMO')] [Alias('ExtractOptions', 'ExportOptions', 'DacExtractOptions', 'DacExportOptions', 'Options', 'Option')] [object]$DacOption, @@ -107,31 +112,17 @@ function Export-DbaDacPackage { [string[]]$Table, [switch]$EnableException ) - + begin { + $null = Test-ExportDirectory -Path $Path + } process { + if (Test-FunctionInterrupt) { return } + if ((Test-Bound -Not -ParameterName Database) -and (Test-Bound -Not -ParameterName ExcludeDatabase) -and (Test-Bound -Not -ParameterName AllUserDatabases)) { Stop-Function -Message "You must specify databases to execute against using either -Database, -ExcludeDatabase or -AllUserDatabases" return } - if (-not (Test-Path $Path)) { - Write-Message -Level Verbose "Assuming that $Path is a file path" - $parentFolder = Split-Path $path -Parent - if (-not (Test-Path $parentFolder)) { - Stop-Function -Message "$parentFolder doesn't exist or access denied" - return - } - $leaf = Split-Path $path -Leaf - $fileName = Join-Path (Get-Item $parentFolder) $leaf - } else { - $fileItem = Get-Item $Path - if ($fileItem -is [System.IO.DirectoryInfo]) { - $parentFolder = $fileItem.FullName - } elseif ($fileItem -is [System.IO.FileInfo]) { - $fileName = $fileItem.FullName - } - } - if (-not $script:core) { $dacfxPath = Resolve-Path -Path "$script:PSModuleRoot\bin\smo\Microsoft.SqlServer.Dac.dll" @@ -208,15 +199,17 @@ function Export-DbaDacPackage { if ($connstring -notmatch 'Database=') { $connstring = "$connstring;Database=$dbname" } - if ($fileName) { - $currentFileName = $fileName - } else { - if ($Type -eq 'Dacpac') { $ext = 'dacpac' } - elseif ($Type -eq 'Bacpac') { $ext = 'bacpac' } - $currentFileName = Join-Path $parentFolder "$cleaninstance-$dbname.$ext" - } + Write-Message -Level Verbose -Message "Using connection string $connstring" + if ($Type -eq 'Dacpac') { + $ext = 'dacpac' + } elseif ($Type -eq 'Bacpac') { + $ext = 'bacpac' + } + + $FilePath = Get-ExportFilePath -Path $PSBoundParameters.Path -FilePath $PSBoundParameters.FilePath -Type $ext -ServerName $instance + #using SMO by default if ($PsCmdlet.ParameterSetName -eq 'SMO') { try { @@ -224,7 +217,7 @@ function Export-DbaDacPackage { } catch { Stop-Function -Message "Could not connect to the connection string $connstring" -Target $instance -Continue } - if (!$DacOption) { + if (-not $DacOption) { $opts = New-DbaDacOption -Type $Type -Action Export } else { $opts = $DacOption @@ -233,20 +226,20 @@ function Export-DbaDacPackage { $null = $output = Register-ObjectEvent -InputObject $dacSvc -EventName "Message" -SourceIdentifier "msg" -Action { $EventArgs.Message.Message } if ($Type -eq 'Dacpac') { - Write-Message -Level Verbose -Message "Initiating Dacpac extract to $currentFileName" + Write-Message -Level Verbose -Message "Initiating Dacpac extract to $FilePath" #not sure how to extract that info from the existing DAC application, leaving 1.0.0.0 for now $version = New-Object System.Version -ArgumentList '1.0.0.0' try { - $dacSvc.Extract($currentFileName, $dbname, $dbname, $version, $null, $tblList, $opts, $null) + $dacSvc.Extract($FilePath, $dbname, $dbname, $version, $null, $tblList, $opts, $null) } catch { Stop-Function -Message "DacServices extraction failure" -ErrorRecord $_ -Continue } finally { Unregister-Event -SourceIdentifier "msg" } } elseif ($Type -eq 'Bacpac') { - Write-Message -Level Verbose -Message "Initiating Bacpac export to $currentFileName" + Write-Message -Level Verbose -Message "Initiating Bacpac export to $FilePath" try { - $dacSvc.ExportBacpac($currentFileName, $dbname, $opts, $tblList, $null) + $dacSvc.ExportBacpac($FilePath, $dbname, $opts, $tblList, $null) } catch { Stop-Function -Message "DacServices export failure" -ErrorRecord $_ -Continue } finally { @@ -259,7 +252,7 @@ function Export-DbaDacPackage { elseif ($Type -eq 'Bacpac') { $action = 'Export' } $cmdConnString = $connstring.Replace('"', "'") - $sqlPackageArgs = "/action:$action /tf:""$currentFileName"" /SourceConnectionString:""$cmdConnString"" $ExtendedParameters $ExtendedProperties" + $sqlPackageArgs = "/action:$action /tf:""$FilePath"" /SourceConnectionString:""$cmdConnString"" $ExtendedParameters $ExtendedProperties" try { $startprocess = New-Object System.Diagnostics.ProcessStartInfo @@ -290,7 +283,7 @@ function Export-DbaDacPackage { InstanceName = $server.ServiceName SqlInstance = $server.DomainInstanceName Database = $dbname - Path = $currentFileName + Path = $FilePath Elapsed = [prettytimespan]($resultstime.Elapsed) Result = $finalResult } | Select-DefaultView -ExcludeProperty ComputerName, InstanceName diff --git a/functions/Export-DbaDbTableData.ps1 b/functions/Export-DbaDbTableData.ps1 index 20fc85682f..4b293e2753 100644 --- a/functions/Export-DbaDbTableData.ps1 +++ b/functions/Export-DbaDbTableData.ps1 @@ -10,7 +10,10 @@ function Export-DbaDbTableData { Pipeline input from Get-DbaDbTable .PARAMETER Path - The output filename and location. If no path is specified, one will be created. If the file already exists, the output will be appended. + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER Encoding Specifies the file encoding. The default is UTF8. @@ -83,6 +86,8 @@ function Export-DbaDbTableData { [parameter(Mandatory, ValueFromPipeline)] [Microsoft.SqlServer.Management.Smo.Table[]]$InputObject, [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [ValidateSet('ASCII', 'BigEndianUnicode', 'Byte', 'String', 'Unicode', 'UTF7', 'UTF8', 'Unknown')] [string]$Encoding = 'UTF8', [string]$BatchSeparator = '', diff --git a/functions/Export-DbaDiagnosticQuery.ps1 b/functions/Export-DbaDiagnosticQuery.ps1 index a058ee844f..0923e4d9f5 100644 --- a/functions/Export-DbaDiagnosticQuery.ps1 +++ b/functions/Export-DbaDiagnosticQuery.ps1 @@ -60,6 +60,7 @@ function Export-DbaDiagnosticQuery { [object[]]$InputObject, [ValidateSet("Excel", "Csv")] [string]$ConvertTo = "Csv", + # No file path because this needs a directory [System.IO.FileInfo]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), [string]$Suffix = "$(Get-Date -format 'yyyyMMddHHmmssms')", [switch]$NoPlanExport, @@ -80,16 +81,15 @@ function Export-DbaDiagnosticQuery { } } - if (!$(Test-Path $Path)) { - try { - New-Item $Path -ItemType Directory -ErrorAction Stop | Out-Null - Write-Message -Level Output -Message "Created directory $Path" - } catch { - Stop-Function -Message "Failed to create directory $Path" -Continue + if (-not (Test-Path -Path $Path)) { + $null = New-Item -ItemType Directory -Path $Path + } else { + if ((Get-Item $Path -ErrorAction Ignore) -isnot [System.IO.DirectoryInfo]) { + Stop-Function -Message "Path ($Path) must be a directory" + return } } } - process { if (Test-FunctionInterrupt) { return } @@ -122,8 +122,8 @@ function Export-DbaDiagnosticQuery { $planfilename = Join-DbaPath -Path $Path -Child "$SqlInstance-DQ-$number-$queryname-$plannr-$Suffix.sqlplan" } - if (!$NoPlanExport) { - Write-Message -Level Output -Message "Exporting $planfilename" + if (-not $NoPlanExport) { + Write-Message -Level Verbose -Message "Exporting $planfilename" if ($plan) {$plan | Out-File -FilePath $planfilename} } } @@ -143,9 +143,12 @@ function Export-DbaDiagnosticQuery { $sqlfilename = Join-DbaPath -Path $Path -Child "$SqlInstance-DQ-$number-$queryname-$sqlnr-$Suffix.sql" } - if (!$NoQueryExport) { - Write-Message -Level Output -Message "Exporting $sqlfilename" - if ($sql) {$sql | Out-File -FilePath $sqlfilename} + if (-not $NoQueryExport) { + Write-Message -Level Verbose -Message "Exporting $sqlfilename" + if ($sql) { + $sql | Out-File -FilePath $sqlfilename + Get-ChildItem -Path $sqlfilename + } } } @@ -155,20 +158,24 @@ function Export-DbaDiagnosticQuery { switch ($ConvertTo) { "Excel" { if ($row.DatabaseSpecific) { - Write-Message -Level Output -Message "Exporting $exceldbfilename" + Write-Message -Level Verbose -Message "Exporting $exceldbfilename" $result | Export-Excel -Path $exceldbfilename -WorkSheetname $Name -AutoSize -AutoFilter -BoldTopRow -FreezeTopRow + Get-ChildItem -Path $exceldbfilename } else { - Write-Message -Level Output -Message "Exporting $excelfilename" + Write-Message -Level Verbose -Message "Exporting $excelfilename" $result | Export-Excel -Path $excelfilename -WorkSheetname $Name -AutoSize -AutoFilter -BoldTopRow -FreezeTopRow + Get-ChildItem -Path $excelfilename } } "csv" { if ($row.DatabaseSpecific) { - Write-Message -Level Output -Message "Exporting $csvdbfilename" + Write-Message -Level Verbose -Message "Exporting $csvdbfilename" $result | Export-Csv -Path $csvdbfilename -NoTypeInformation -Append + Get-ChildItem -Path $csvdbfilename } else { - Write-Message -Level Output -Message "Exporting $csvfilename" + Write-Message -Level Verbose -Message "Exporting $csvfilename" $result | Export-Csv -Path $csvfilename -NoTypeInformation -Append + Get-ChildItem -Path $csvfilename } } } diff --git a/functions/Export-DbaExecutionPlan.ps1 b/functions/Export-DbaExecutionPlan.ps1 index cc0e470f60..28a2bce57a 100644 --- a/functions/Export-DbaExecutionPlan.ps1 +++ b/functions/Export-DbaExecutionPlan.ps1 @@ -39,7 +39,7 @@ function Export-DbaExecutionPlan { .PARAMETER Confirm Prompts you for confirmation before executing any changing operations within the command. - .PARAMETER PipedObject + .PARAMETER InputObject Internal parameter .PARAMETER EnableException @@ -87,15 +87,16 @@ function Export-DbaExecutionPlan { [PSCredential]$SqlCredential, [object[]]$Database, [object[]]$ExcludeDatabase, - [parameter(ParameterSetName = 'Piped', Mandatory)] - [parameter(ParameterSetName = 'NotPiped', Mandatory)] + [parameter(ParameterSetName = 'Piped')] + [parameter(ParameterSetName = 'NotPiped')] + # No file path because this needs a directory [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), [parameter(ParameterSetName = 'NotPiped')] [datetime]$SinceCreation, [parameter(ParameterSetName = 'NotPiped')] [datetime]$SinceLastExecution, [Parameter(ParameterSetName = 'Piped', Mandatory, ValueFromPipeline)] - [object[]]$PipedObject, + [object[]]$InputObject, [switch]$EnableException ) @@ -144,12 +145,18 @@ function Export-DbaExecutionPlan { } process { - if (!(Test-Path $Path)) { - $null = New-Item -ItemType Directory -Path $Path + + if ((Test-Bound -ParamterName Path) -and ((Get-Item $Path -ErrorAction Ignore) -isnot [System.IO.DirectoryInfo])) { + if ($Path -eq (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport')) { + $null = New-Item -ItemType Directory -Path $Path + } else { + Stop-Function -Message "Path ($Path) must be a directory" + return + } } - if ($PipedObject) { - foreach ($object in $pipedobject) { + if ($InputObject) { + foreach ($object in $InputObject) { Export-Plan $object return } diff --git a/functions/Export-DbaInstance.ps1 b/functions/Export-DbaInstance.ps1 index 36edf61e93..b185b40978 100644 --- a/functions/Export-DbaInstance.ps1 +++ b/functions/Export-DbaInstance.ps1 @@ -44,10 +44,10 @@ function Export-DbaInstance { Alternative Windows credentials for exporting Linked Servers and Credentials. Accepts credential objects (Get-Credential) .PARAMETER Path - The path to the export file + Specifies the directory where the file or files will be exported. - .PARAMETER SharedPath - Specifies the network location for the backup files. The SQL Server service accounts on both Source and Destination must have read/write permission to access this location. + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER WithReplace If this switch is used, databases are restored from backup using WITH REPLACE. This is useful if you want to stage some complex file paths. @@ -89,6 +89,9 @@ function Export-DbaInstance { .PARAMETER ScriptingOption Add scripting options to scripting output for all objects except Registered Servers and Extended Events. + .PARAMETER Append + Append to the target file instead of overwriting. + .PARAMETER EnableException By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message. This avoids overwhelming you with "sea of red" exceptions, but is inconvenient because it basically disables advanced scripting. @@ -124,18 +127,19 @@ function Export-DbaInstance { [PSCredential]$SqlCredential, [PSCredential]$Credential, [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [switch]$NoRecovery, [switch]$IncludeDbMasterKey, [ValidateSet('Databases', 'Logins', 'AgentServer', 'Credentials', 'LinkedServers', 'SpConfigure', 'CentralManagementServer', 'DatabaseMail', 'SysDbUserObjects', 'SystemTriggers', 'BackupDevices', 'Audits', 'Endpoints', 'ExtendedEvents', 'PolicyManagement', 'ResourceGovernor', 'ServerAuditSpecifications', 'CustomErrors', 'ServerRoles', 'AvailabilityGroups', 'ReplicationSettings')] [string[]]$Exclude, [string]$BatchSeparator = 'GO', + [switch]$Append, [Microsoft.SqlServer.Management.Smo.ScriptingOptions]$ScriptingOption, [switch]$EnableException ) begin { - if (-not ((Get-Item $Path -ErrorAction Ignore) -is [System.IO.DirectoryInfo])) { - Stop-Function -Message "Path must be a directory" - } + $null = Test-ExportDirectory -Path $Path if (-not $ScriptingOption) { $ScriptingOption = New-DbaScriptingOption @@ -173,7 +177,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting SQL Server Configuration" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting SQL Server Configuration" - Export-DbaSpConfigure -SqlInstance $server -Path "$Path\$fileCounter-sp_configure.sql" + Export-DbaSpConfigure -SqlInstance $server -FilePath "$Path\$fileCounter-sp_configure.sql" if (-not (Test-Path "$Path\$fileCounter-sp_configure.sql")) { $fileCounter-- } @@ -183,7 +187,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting custom errors (user defined messages)" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting custom errors (user defined messages)" - $null = Get-DbaCustomError -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-customererrors.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaCustomError -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-customererrors.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-customererrors.sql" if (-not (Test-Path "$Path\$fileCounter-customererrors.sql")) { $fileCounter-- @@ -194,7 +198,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting server roles" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting server roles" - $null = Get-DbaInstanceRole -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-serverroles.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaInstanceRole -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-serverroles.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-serverroles.sql" if (-not (Test-Path "$Path\$fileCounter-serverroles.sql")) { $fileCounter-- @@ -205,7 +209,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting SQL credentials" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting SQL credentials" - $null = Export-DbaCredential -SqlInstance $server -Credential $Credential -Path "$Path\$fileCounter-credentials.sql" -Append + $null = Export-DbaCredential -SqlInstance $server -Credential $Credential -FilePath "$Path\$fileCounter-credentials.sql" -Append:$Append Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-credentials.sql" if (-not (Test-Path "$Path\$fileCounter-credentials.sql")) { $fileCounter-- @@ -216,11 +220,11 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting database mail" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting database mail" - $null = Get-DbaDbMailConfig -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-dbmail.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaDbMailAccount -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-dbmail.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaDbMailProfile -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-dbmail.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaDbMailServer -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-dbmail.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaDbMail -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-dbmail.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaDbMailConfig -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-dbmail.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaDbMailAccount -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-dbmail.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaDbMailProfile -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-dbmail.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaDbMailServer -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-dbmail.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaDbMail -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-dbmail.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-dbmail.sql" if (-not (Test-Path "$Path\$fileCounter-dbmail.sql")) { $fileCounter-- @@ -231,8 +235,8 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting Central Management Server" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting Central Management Server" - $null = Get-DbaRegServerGroup -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-regserver.sql" -Append -BatchSeparator 'GO' - $null = Get-DbaRegServer -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-regserver.sql" -Append -BatchSeparator 'GO' + $null = Get-DbaRegServerGroup -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-regserver.sql" -Append:$Append -BatchSeparator 'GO' + $null = Get-DbaRegServer -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-regserver.sql" -Append:$Append -BatchSeparator 'GO' Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-regserver.sql" if (-not (Test-Path "$Path\$fileCounter-regserver.sql")) { $fileCounter-- @@ -243,7 +247,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting Backup Devices" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting Backup Devices" - $null = Get-DbaBackupDevice -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-backupdevices.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaBackupDevice -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-backupdevices.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-backupdevices.sql" if (-not (Test-Path "$Path\$fileCounter-backupdevices.sql")) { $fileCounter-- @@ -254,7 +258,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting linked servers" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting linked servers" - Export-DbaLinkedServer -SqlInstance $server -Path "$Path\$fileCounter-linkedservers.sql" -Credential $Credential -Append + Export-DbaLinkedServer -SqlInstance $server -FilePath "$Path\$fileCounter-linkedservers.sql" -Credential $Credential -Append:$Append if (-not (Test-Path "$Path\$fileCounter-linkedservers.sql")) { $fileCounter-- } @@ -264,7 +268,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting System Triggers" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting System Triggers" - $null = Get-DbaInstanceTrigger -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-servertriggers.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaInstanceTrigger -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-servertriggers.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption $triggers = Get-Content -Path "$Path\$fileCounter-servertriggers.sql" -Raw -ErrorAction Ignore if ($triggers) { $triggers = $triggers.ToString() -replace 'CREATE TRIGGER', "GO`r`nCREATE TRIGGER" @@ -281,7 +285,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting database restores" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting database restores" - Get-DbaBackupHistory -SqlInstance $server -Last | Restore-DbaDatabase -SqlInstance $server -NoRecovery:$NoRecovery -WithReplace -OutputScriptOnly -WarningAction SilentlyContinue | Out-File -FilePath "$Path\$fileCounter-databases.sql" -Append + Get-DbaBackupHistory -SqlInstance $server -Last | Restore-DbaDatabase -SqlInstance $server -NoRecovery:$NoRecovery -WithReplace -OutputScriptOnly -WarningAction SilentlyContinue | Out-File -FilePath "$Path\$fileCounter-databases.sql" -Append:$Append Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-databases.sql" if (-not (Test-Path "$Path\$fileCounter-databases.sql")) { $fileCounter-- @@ -292,7 +296,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting logins" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting logins" - Export-DbaLogin -SqlInstance $server -Path "$Path\$fileCounter-logins.sql" -Append -WarningAction SilentlyContinue + Export-DbaLogin -SqlInstance $server -FilePath "$Path\$fileCounter-logins.sql" -Append:$Append -WarningAction SilentlyContinue if (-not (Test-Path "$Path\$fileCounter-logins.sql")) { $fileCounter-- } @@ -302,7 +306,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting Audits" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting Audits" - $null = Get-DbaInstanceAudit -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-audits.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaInstanceAudit -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-audits.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-audits.sql" if (-not (Test-Path "$Path\$fileCounter-audits.sql")) { $fileCounter-- @@ -313,7 +317,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting Server Audit Specifications" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting Server Audit Specifications" - $null = Get-DbaInstanceAuditSpecification -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-auditspecs.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaInstanceAuditSpecification -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-auditspecs.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-auditspecs.sql" if (-not (Test-Path "$Path\$fileCounter-auditspecs.sql")) { $fileCounter-- @@ -324,7 +328,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting Endpoints" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting Endpoints" - $null = Get-DbaEndpoint -SqlInstance $server | Where-Object IsSystemObject -eq $false | Export-DbaScript -Path "$Path\$fileCounter-endpoints.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaEndpoint -SqlInstance $server | Where-Object IsSystemObject -eq $false | Export-DbaScript -FilePath "$Path\$fileCounter-endpoints.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-endpoints.sql" if (-not (Test-Path "$Path\$fileCounter-endpoints.sql")) { $fileCounter-- @@ -335,9 +339,9 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting Policy Management" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting Policy Management" - $null = Get-DbaPbmCondition -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-policymanagement.sql" -Append -BatchSeparator $BatchSeparator - $null = Get-DbaPbmObjectSet -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-policymanagement.sql" -Append -BatchSeparator $BatchSeparator - $null = Get-DbaPbmPolicy -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-policymanagement.sql" -Append -BatchSeparator $BatchSeparator + $null = Get-DbaPbmCondition -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-policymanagement.sql" -Append:$Append -BatchSeparator $BatchSeparator + $null = Get-DbaPbmObjectSet -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-policymanagement.sql" -Append:$Append -BatchSeparator $BatchSeparator + $null = Get-DbaPbmPolicy -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-policymanagement.sql" -Append:$Append -BatchSeparator $BatchSeparator Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-policymanagement.sql" if (-not (Test-Path "$Path\$fileCounter-policymanagement.sql")) { $fileCounter-- @@ -348,10 +352,10 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting Resource Governor" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting Resource Governor" - $null = Get-DbaResourceGovernor -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-resourcegov.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaRgClassifierFunction -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-resourcegov.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaRgResourcePool -SqlInstance $server | Where-Object Name -notin 'default', 'internal' | Export-DbaScript -Path "$Path\$fileCounter-resourcegov.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaRgWorkloadGroup -SqlInstance $server | Where-Object Name -notin 'default', 'internal' | Export-DbaScript -Path "$Path\$fileCounter-resourcegov.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaResourceGovernor -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-resourcegov.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaRgClassifierFunction -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-resourcegov.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaRgResourcePool -SqlInstance $server | Where-Object Name -notin 'default', 'internal' | Export-DbaScript -FilePath "$Path\$fileCounter-resourcegov.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaRgWorkloadGroup -SqlInstance $server | Where-Object Name -notin 'default', 'internal' | Export-DbaScript -FilePath "$Path\$fileCounter-resourcegov.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption $null = Add-Content -Value "ALTER RESOURCE GOVERNOR RECONFIGURE" -Path "$Path\$stepCounter-resourcegov.sql" Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-resourcegov.sql" if (-not (Test-Path "$Path\$fileCounter-resourcegov.sql")) { @@ -363,7 +367,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting Extended Events" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting Extended Events" - $null = Get-DbaXESession -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-extendedevents.sql" -Append -BatchSeparator 'GO' + $null = Get-DbaXESession -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-extendedevents.sql" -Append:$Append -BatchSeparator 'GO' Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-extendedevents.sql" if (-not (Test-Path "$Path\$fileCounter-extendedevents.sql")) { $fileCounter-- @@ -375,12 +379,12 @@ function Export-DbaInstance { Write-Message -Level Verbose -Message "Exporting job server" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting job server" - $null = Get-DbaAgentJobCategory -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-sqlagent.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaAgentOperator -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-sqlagent.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaAgentAlert -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-sqlagent.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaAgentProxy -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-sqlagent.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaAgentSchedule -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-sqlagent.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption - $null = Get-DbaAgentJob -SqlInstance $server | Export-DbaScript -Path "$Path\$fileCounter-sqlagent.sql" -Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaAgentJobCategory -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-sqlagent.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaAgentOperator -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-sqlagent.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaAgentAlert -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-sqlagent.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaAgentProxy -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-sqlagent.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaAgentSchedule -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-sqlagent.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption + $null = Get-DbaAgentJob -SqlInstance $server | Export-DbaScript -FilePath "$Path\$fileCounter-sqlagent.sql" -Append:$Append -BatchSeparator $BatchSeparator -ScriptingOptionsObject $ScriptingOption Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-sqlagent.sql" if (-not (Test-Path "$Path\$fileCounter-sqlagent.sql")) { $fileCounter-- @@ -391,7 +395,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting replication settings" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting replication settings" - $null = Export-DbaRepServerSetting -SqlInstance $instance -SqlCredential $SqlCredential -Path "$Path\$fileCounter-replication.sql" + $null = Export-DbaRepServerSetting -SqlInstance $instance -SqlCredential $SqlCredential -FilePath "$Path\$fileCounter-replication.sql" Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-replication.sql" if (-not (Test-Path "$Path\$fileCounter-replication.sql")) { $fileCounter-- @@ -402,7 +406,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting user objects in system databases (this can take a minute)." Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting user objects in system databases (this can take a minute)." - $null = Get-DbaSysDbUserObjectScript -SqlInstance $server | Out-File -FilePath "$Path\$fileCounter-userobjectsinsysdbs.sql" -Append + $null = Get-DbaSysDbUserObjectScript -SqlInstance $server | Out-File -FilePath "$Path\$fileCounter-userobjectsinsysdbs.sql" -Append:$Append Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-userobjectsinsysdbs.sql" if (-not (Test-Path "$Path\$fileCounter-userobjectsinsysdbs.sql")) { $fileCounter-- @@ -413,7 +417,7 @@ function Export-DbaInstance { $fileCounter++ Write-Message -Level Verbose -Message "Exporting availability group" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Exporting availability groups" - $null = Get-DbaAvailabilityGroup -SqlInstance $server -WarningAction SilentlyContinue | Export-DbaScript -Path "$Path\$fileCounter-DbaAvailabilityGroups.sql" -Append -BatchSeparator $BatchSeparator #-ScriptingOptionsObject $ScriptingOption + $null = Get-DbaAvailabilityGroup -SqlInstance $server -WarningAction SilentlyContinue | Export-DbaScript -FilePath "$Path\$fileCounter-DbaAvailabilityGroups.sql" -Append:$Append -BatchSeparator $BatchSeparator #-ScriptingOptionsObject $ScriptingOption Get-ChildItem -ErrorAction Ignore -Path "$Path\$fileCounter-DbaAvailabilityGroups.sql" if (-not (Test-Path "$Path\$fileCounter-DbaAvailabilityGroups.sql")) { $fileCounter-- diff --git a/functions/Export-DbaLinkedServer.ps1 b/functions/Export-DbaLinkedServer.ps1 index 7f002b93e5..2ee7c559e1 100644 --- a/functions/Export-DbaLinkedServer.ps1 +++ b/functions/Export-DbaLinkedServer.ps1 @@ -18,7 +18,10 @@ function Export-DbaLinkedServer { Login to the target OS using alternative linked servers. Accepts credential objects (Get-Credential) .PARAMETER Path - The path to the exported sql file. + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER LinkedServer The linked server(s) to export. If unspecified, all linked servers will be processed. @@ -64,12 +67,18 @@ function Export-DbaLinkedServer { [PSCredential]$SqlCredential, [PSCredential]$Credential, [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [switch]$ExcludePassword, [switch]$Append, [Microsoft.SqlServer.Management.Smo.LinkedServer[]]$InputObject, [switch]$EnableException ) + begin { + $null = Test-ExportDirectory -Path $Path + } process { + if (Test-FunctionInterrupt) { return } foreach ($instance in $SqlInstance) { try { $server = Connect-SqlInstance -SqlInstance $instance -SqlCredential $sqlcredential -MinimumVersion 9 @@ -102,8 +111,7 @@ function Export-DbaLinkedServer { return } - $timenow = (Get-Date -uformat "%m%d%Y%H%M%S") - $path = Join-DbaPath -Path $Path -Child "$($server.name.replace('\', '$'))-$timenow-linkedserver.sql" + $FilePath = Get-ExportFilePath -Path $PSBoundParameters.Path -FilePath $PSBoundParameters.FilePath -Type sql -ServerName $instance $sql = @() @@ -134,13 +142,13 @@ function Export-DbaLinkedServer { } try { if ($Append) { - Add-Content -Path $path -Value $sql + Add-Content -Path $FilePath -Value $sql } else { - Set-Content -Path $path -Value $sql + Set-Content -Path $FilePath -Value $sql } - Get-ChildItem -Path $path + Get-ChildItem -Path $FilePath } catch { - Stop-Function -Message "Can't write to $path" -ErrorRecord $_ -Continue + Stop-Function -Message "Can't write to $FilePath" -ErrorRecord $_ -Continue } } } diff --git a/functions/Export-DbaLogin.ps1 b/functions/Export-DbaLogin.ps1 index 83d4b2c251..6a15d33f52 100644 --- a/functions/Export-DbaLogin.ps1 +++ b/functions/Export-DbaLogin.ps1 @@ -22,7 +22,10 @@ function Export-DbaLogin { The database(s) to process. Options for this list are auto-populated from the server. If unspecified, all databases will be processed. .PARAMETER Path - The file to write to. + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER NoClobber If this switch is enabled, a file already existing at the path specified by Path will not be overwritten. @@ -126,8 +129,9 @@ function Export-DbaLogin { [object[]]$Login, [object[]]$ExcludeLogin, [object[]]$Database, - [Alias("OutFile", "FilePath", "FileName")] [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [Alias("NoOverwrite")] [switch]$NoClobber, [switch]$Append, @@ -143,24 +147,11 @@ function Export-DbaLogin { ) begin { - if ($Path) { - if ($Path -notlike "*\*") { - $Path = ".\$Path" - } - $directory = Split-Path $Path - $exists = Test-Path $directory - - if ($exists -eq $false) { - Write-Message -Level Warning -Message "Parent directory $directory does not exist" - } - } - + $null = Test-ExportDirectory -Path $Path $outsql = @() } process { - if (Test-FunctionInterrupt) { - return - } + if (Test-FunctionInterrupt) { return } if (-not $InputObject -and -not $SqlInstance) { Stop-Function -Message "You must pipe in a login, database, or server or specify a SqlInstance" @@ -263,7 +254,7 @@ function Export-DbaLogin { } if ($Pscmdlet.ShouldProcess("Outfile", "Adding T-SQL for login $userName")) { - if ($Path) { + if ($Path -or $FilePath) { Write-Message -Level Verbose -Message "Exporting $userName" } @@ -474,9 +465,10 @@ function Export-DbaLogin { $sql += "`r`nGO" } - if ($Path) { - $sql | Out-File -Encoding UTF8 -FilePath $Path -Append:$Append -NoClobber:$NoClobber - Get-ChildItem $Path + if ($Path -Or $FilePath) { + $FilePath = Get-ExportFilePath -Path $PSBoundParameters.Path -FilePath $PSBoundParameters.FilePath -Type sql -ServerName $instance + $sql | Out-File -Encoding UTF8 -FilePath $FilePath -Append:$Append -NoClobber:$NoClobber + Get-ChildItem $FilePath } else { $sql } diff --git a/functions/Export-DbaPfDataCollectorSetTemplate.ps1 b/functions/Export-DbaPfDataCollectorSetTemplate.ps1 index 53b9d4260b..f1e95cca24 100644 --- a/functions/Export-DbaPfDataCollectorSetTemplate.ps1 +++ b/functions/Export-DbaPfDataCollectorSetTemplate.ps1 @@ -18,7 +18,10 @@ function Export-DbaPfDataCollectorSetTemplate { The name of the collector set(s) to export. .PARAMETER Path - The path to export the file. Can be .xml or directory. + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER InputObject Accepts the object output by Get-DbaPfDataCollectorSetTemplate via the pipeline. @@ -56,12 +59,19 @@ function Export-DbaPfDataCollectorSetTemplate { [PSCredential]$Credential, [Alias("DataCollectorSet")] [string[]]$CollectorSet, - [string]$Path = "$home\Documents\Performance Monitor Templates", + [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [Parameter(ValueFromPipeline)] [object[]]$InputObject, [switch]$EnableException ) + begin { + $null = Test-ExportDirectory -Path $Path + } process { + if (Test-FunctionInterrupt) { return } + if ($InputObject.Credential -and (Test-Bound -ParameterName Credential -Not)) { $Credential = $InputObject.Credential } @@ -78,19 +88,14 @@ function Export-DbaPfDataCollectorSetTemplate { return } - $csname = Remove-InvalidFileNameChars -Name $object.Name - - if ($path.EndsWith(".xml")) { - $filename = $path - } else { - $filename = "$path\$csname.xml" - if (-not (Test-Path -Path $path)) { - $null = New-Item -Type Directory -Path $path - } + if (-not $FilePath) { + $csname = Remove-InvalidFileNameChars -Name $object.Name + $FilePath = "$Path\$csname.xml" } + Write-Message -Level Verbose -Message "Wrote $csname to $filename." - Set-Content -Path $filename -Value $object.Xml -Encoding Unicode - Get-ChildItem -Path $filename + Set-Content -Path $FilePath -Value $object.Xml -Encoding Unicode + Get-ChildItem -Path $FilePath } } } \ No newline at end of file diff --git a/functions/Export-DbaRegServer.ps1 b/functions/Export-DbaRegServer.ps1 index 9554df9c76..da6dec92d2 100644 --- a/functions/Export-DbaRegServer.ps1 +++ b/functions/Export-DbaRegServer.ps1 @@ -16,7 +16,10 @@ function Export-DbaRegServer { Used to specify how the login and passwords are persisted. Valid values include None, PersistLoginName and PersistLoginNameAndPassword. .PARAMETER Path - The path to the exported files. If no path is specified, one will be created. This is expected to be a directory. + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER InputObject Enables piping from Get-DbaRegServer, Get-DbaRegServerGroup, CSVs and other objects. @@ -65,21 +68,19 @@ function Export-DbaRegServer { [parameter(ValueFromPipeline)] [object[]]$InputObject, [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [ValidateSet("None", "PersistLoginName", "PersistLoginNameAndPassword")] [string]$CredentialPersistenceType = "None", [switch]$EnableException ) begin { - if (-not (test-path $Path)) { - New-Item -Path $Path -ItemType Directory - } else { - if ( -not (Get-Item -Path $Path).PSIsContainer) { - Stop-function -Message "Path provided is an already-existing file. Please provide a directory name." - } - } + $null = Test-ExportDirectory -Path $Path $timeNow = (Get-Date -uformat "%m%d%Y%H%M%S") } process { + if (Test-FunctionInterrupt) { return } + foreach ($instance in $SqlInstance) { $InputObject += Get-DbaRegServerGroup -SqlInstance $instance -SqlCredential $SqlCredential -Id 1 } @@ -90,21 +91,25 @@ function Export-DbaRegServer { $object = Get-DbaRegServerGroup -SqlInstance $object.ParentServer -Id 1 } if ($object -is [Microsoft.SqlServer.Management.RegisteredServers.RegisteredServer]) { - $serverName = $object.SqlInstance.Replace('\', '$'); - $regservername = $object.Name.Replace('\', '$') - $ExportFileName = "$serverName-regserver-$regservername-$timeNow.xml" - $FullExportFile = Join-DbaPath -Path $Path -Child $ExportFileName - $object.Export($FullExportFile, $CredentialPersistenceType) + if (-not $FilePath) { + $serverName = $object.SqlInstance.Replace('\', '$'); + $regservername = $object.Name.Replace('\', '$') + $ExportFileName = "$serverName-regserver-$regservername-$timeNow.xml" + $FilePath = Join-DbaPath -Path $Path -Child $ExportFileName + $object.Export($FilePath, $CredentialPersistenceType) + } } elseif ($object -is [Microsoft.SqlServer.Management.RegisteredServers.ServerGroup]) { - $servername = $object.SqlInstance.Replace('\', '$') - $regservergroup = $object.Name.Replace('\', '$') - $ExportFileName = "$serverName-reggroup-$regservergroup-$timeNow.xml" - $FullExportFile = Join-DbaPath -Path $Path -Child $ExportFileName - $object.Export($FullExportFile, $CredentialPersistenceType) + if (-not $FilePath) { + $servername = $object.SqlInstance.Replace('\', '$') + $regservergroup = $object.Name.Replace('\', '$') + $ExportFileName = "$serverName-reggroup-$regservergroup-$timeNow.xml" + $FilePath = Join-DbaPath -Path $Path -Child $ExportFileName + $object.Export($FilePath, $CredentialPersistenceType) + } } else { Stop-Function -Message "InputObject is not a registered server or server group" -Continue } - Get-ChildItem $FullExportFile -ErrorAction Stop + Get-ChildItem $FilePath -ErrorAction Stop } catch { Stop-Function -Message "Failure" -ErrorRecord $_ } diff --git a/functions/Export-DbaRepServerSetting.ps1 b/functions/Export-DbaRepServerSetting.ps1 index 7cbb822f09..eff20197d9 100644 --- a/functions/Export-DbaRepServerSetting.ps1 +++ b/functions/Export-DbaRepServerSetting.ps1 @@ -13,7 +13,10 @@ function Export-DbaRepServerSetting { Login to the target instance using alternative credentials. Windows and SQL Authentication supported. Accepts credential objects (Get-Credential) .PARAMETER Path - Specifies the path to a file which will contain the output. + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER Passthru Output script to console @@ -72,6 +75,8 @@ function Export-DbaRepServerSetting { [DbaInstanceParameter[]]$SqlInstance, [PSCredential]$SqlCredential, [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [object[]]$ScriptOption, [Parameter(ValueFromPipeline)] [Microsoft.SqlServer.Replication.ReplicationServer[]]$InputObject, @@ -82,38 +87,17 @@ function Export-DbaRepServerSetting { [switch]$Append, [switch]$EnableException ) + begin { + $null = Test-ExportDirectory -Path $Path + } process { + if (Test-FunctionInterrupt) { return } foreach ($instance in $SqlInstance) { $InputObject += Get-DbaRepServer -SqlInstance $instance -SqlCredential $sqlcredential } foreach ($repserver in $InputObject) { - $server = $repserver.SqlServerName - $timenow = (Get-Date -uformat "%m%d%Y%H%M%S") - $path = Join-DbaPath -Path $Path -Child "$($server.replace('\', '$'))-$timenow-replication.sql" - - if (Test-Path $Path -PathType Container) { - $timenow = (Get-Date -uformat "%m%d%Y%H%M%S") - $filepath = Join-Path -Path $Path -ChildPath "$($server.name.replace('\', '$'))-$timenow-replication.sql" - } elseif (Test-Path $Path -PathType Leaf) { - if ($SqlInstance.Count -gt 1) { - $timenow = (Get-Date -uformat "%m%d%Y%H%M%S") - $PathData = Get-ChildItem $Path - $filepath = "$($PathData.DirectoryName)\$($server.name.replace('\', '$'))-$timenow-$($PathData.Name)" - } else { - $filepath = $Path - } - } - - If (-not $filepath) { - $filepath = $Path - } - - $topdir = Split-Path -Path $filepath - - if (-not (Test-Path -Path $topdir)) { - New-Item -Path $topdir -ItemType Directory - } + $FilePath = Get-ExportFilePath -Path $PSBoundParameters.Path -FilePath $PSBoundParameters.FilePath -Type sql -ServerName $repserver.SqlServerName try { if (-not $ScriptOption) { @@ -131,13 +115,11 @@ function Export-DbaRepServerSetting { if ($Passthru) { "exec sp_dropdistributor @no_checks = 1, @ignore_distributor = 1" | Out-String $out | Out-String + continue } - if ($filepath) { - - "exec sp_dropdistributor @no_checks = 1, @ignore_distributor = 1" | Out-File -FilePath $filepath -Encoding $encoding -Append - $out | Out-File -FilePath $filepath -Encoding $encoding -Append:$Append - } + "exec sp_dropdistributor @no_checks = 1, @ignore_distributor = 1" | Out-File -FilePath $FilePath -Encoding $encoding -Append + $out | Out-File -FilePath $FilePath -Encoding $encoding -Append:$Append } } } \ No newline at end of file diff --git a/functions/Export-DbaScript.ps1 b/functions/Export-DbaScript.ps1 index 2ae8bcfa4b..1c1052a752 100644 --- a/functions/Export-DbaScript.ps1 +++ b/functions/Export-DbaScript.ps1 @@ -8,9 +8,11 @@ function Export-DbaScript { .PARAMETER InputObject A SQL Management Object such as the one returned from Get-DbaLogin - .PARAMETER Path - The output filename and location. If no path is specified, one will be created. If the file already exists, the output will be appended. + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER Encoding Specifies the file encoding. The default is UTF8. @@ -130,6 +132,8 @@ function Export-DbaScript { [Alias("ScriptingOptionObject")] [Microsoft.SqlServer.Management.Smo.ScriptingOptions]$ScriptingOptionsObject, [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [ValidateSet('ASCII', 'BigEndianUnicode', 'Byte', 'String', 'Unicode', 'UTF7', 'UTF8', 'Unknown')] [string]$Encoding = 'UTF8', [string]$BatchSeparator = '', @@ -139,15 +143,15 @@ function Export-DbaScript { [switch]$Append, [switch]$EnableException ) - begin { + $null = Test-ExportDirectory -Path $Path $executingUser = [Security.Principal.WindowsIdentity]::GetCurrent().Name $commandName = $MyInvocation.MyCommand.Name - $timeNow = (Get-Date -uformat "%m%d%Y%H%M%S") $prefixArray = @() } process { + if (Test-FunctionInterrupt) { return } foreach ($object in $InputObject) { $typename = $object.GetType().ToString() @@ -194,12 +198,8 @@ function Export-DbaScript { $scripter.Options = $ScriptingOptionsObject } - if (!$passthru) { - if ($path) { - $actualPath = $path - } else { - $actualPath = "$serverName-$shortype-Export-$timeNow.sql" - } + if (-not $passthru) { + $FilePath = Get-ExportFilePath -Path $PSBoundParameters.Path -FilePath $PSBoundParameters.FilePath -Type sql -ServerName $serverName } if ($NoPrefix) { @@ -211,18 +211,17 @@ function Export-DbaScript { if ($passthru) { $prefix | Out-String } else { - if ($prefixArray -notcontains $actualPath) { - - if ((Test-Path -Path $actualPath) -and $NoClobber) { - Stop-Function -Message "File already exists. If you want to overwrite it remove the -NoClobber parameter. If you want to append data, please Use -Append parameter." -Target $actualPath -Continue + if ($prefixArray -notcontains $FilePath) { + if ((Test-Path -Path $FilePath) -and $NoClobber) { + Stop-Function -Message "File already exists. If you want to overwrite it remove the -NoClobber parameter. If you want to append data, please Use -Append parameter." -Target $FilePath -Continue } #Only at the first output we use the passed variables Append & NoClobber. For this execution the next ones need to buse -Append - $prefix | Out-File -FilePath $actualPath -Encoding $encoding -Append:$Append -NoClobber:$NoClobber - $prefixArray += $actualPath + $prefix | Out-File -FilePath $FilePath -Encoding $encoding -Append:$Append -NoClobber:$NoClobber + $prefixArray += $FilePath } } - if ($Pscmdlet.ShouldProcess($env:computername, "Exporting $object from $server to $actualPath")) { + if ($Pscmdlet.ShouldProcess($env:computername, "Exporting $object from $server to $FilePath")) { Write-Message -Level Verbose -Message "Exporting $object" if ($passthru) { @@ -250,14 +249,14 @@ function Export-DbaScript { if ($ScriptingOptionsObject.ScriptBatchTerminator) { $ScriptingOptionsObject.AppendToFile = $true $ScriptingOptionsObject.ToFileOnly = $true - $ScriptingOptionsObject.FileName = $actualPath + $ScriptingOptionsObject.FileName = $FilePath $object.Script($ScriptingOptionsObject) } else { foreach ($script in $scripter.EnumScript($object)) { if ($BatchSeparator -ne "") { $script = "$script`r`n$BatchSeparator`r`n" } - $script | Out-File -FilePath $actualPath -Encoding $encoding -Append + $script | Out-File -FilePath $FilePath -Encoding $encoding -Append } } @@ -270,13 +269,13 @@ function Export-DbaScript { if ($BatchSeparator -ne "") { $script = "$script`r`n$BatchSeparator`r`n" } - $script | Out-File -FilePath $actualPath -Encoding $encoding -Append + $script | Out-File -FilePath $FilePath -Encoding $encoding -Append } } if (-not $passthru) { - Write-Message -Level Verbose -Message "Exported $object on $($server.Name) to $actualPath" - Get-ChildItem -Path $actualPath + Write-Message -Level Verbose -Message "Exported $object on $($server.Name) to $FilePath" + Get-ChildItem -Path $FilePath } } } catch { diff --git a/functions/Export-DbaSpConfigure.ps1 b/functions/Export-DbaSpConfigure.ps1 index 7a2634214f..b679d1a561 100644 --- a/functions/Export-DbaSpConfigure.ps1 +++ b/functions/Export-DbaSpConfigure.ps1 @@ -14,9 +14,10 @@ function Export-DbaSpConfigure { Login to the target instance using alternative credentials. Windows and SQL Authentication supported. Accepts credential objects (Get-Credential) .PARAMETER Path - Specifies the path to a file which will contain the sp_configure queries necessary to replicate the configuration settings on another instance. This file is suitable for input into Import-DbaSPConfigure. - If not specified will output to My Documents folder with default name of ServerName-MMDDYYYYhhmmss-sp_configure.sql - If a directory is passed then uses default name of ServerName-MMDDYYYYhhmmss-sp_configure.sql + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER EnableException By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message. @@ -68,41 +69,23 @@ function Export-DbaSpConfigure { [DbaInstanceParameter[]]$SqlInstance, [PSCredential]$SqlCredential, [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [switch]$EnableException ) + begin { + $null = Test-ExportDirectory -Path $Path + } process { + if (Test-FunctionInterrupt) { return } foreach ($instance in $SqlInstance) { try { $server = Connect-SqlInstance -SqlInstance $instance -SqlCredential $sqlcredential -MinimumVersion 9 } catch { Stop-Function -Message "Error occurred while establishing connection to $instance" -Category ConnectionError -ErrorRecord $_ -Target $instance -Continue } - $timenow = (Get-Date -uformat "%m%d%Y%H%M%S") - $filepath = Join-DbaPath -Path $Path -Child "$($server.name.replace('\', '$'))-$timenow-sp_configure.sql" - - if (Test-Path $Path -PathType Container) { - $timenow = (Get-Date -uformat "%m%d%Y%H%M%S") - $filepath = Join-Path -Path $Path -ChildPath "$($server.name.replace('\', '$'))-$timenow-sp_configure.sql" - } elseif (Test-Path $Path -PathType Leaf) { - if ($SqlInstance.Count -gt 1) { - $timenow = (Get-Date -uformat "%m%d%Y%H%M%S") - $PathData = Get-ChildItem $Path - $filepath = "$($PathData.DirectoryName)\$($server.name.replace('\', '$'))-$timenow-$($PathData.Name)" - } else { - $filepath = $Path - } - } - - If (-not $filepath) { - $filepath = $Path - } - - $topdir = Split-Path -Path $filepath - - if (-not (Test-Path -Path $topdir)) { - New-Item -Path $topdir -ItemType Directory - } + $FilePath = Get-ExportFilePath -Path $PSBoundParameters.Path -FilePath $PSBoundParameters.FilePath -Type sql -ServerName $instance $ShowAdvancedOptions = $server.Configuration.ShowAdvancedOptions.ConfigValue if ($ShowAdvancedOptions -eq 0) { @@ -115,25 +98,25 @@ function Export-DbaSpConfigure { } try { - Set-Content -Path $filepath "EXEC sp_configure 'show advanced options' , 1; RECONFIGURE WITH OVERRIDE" + Set-Content -Path $FilePath "EXEC sp_configure 'show advanced options' , 1; RECONFIGURE WITH OVERRIDE" } catch { - Stop-Function -Message "Can't write to $filepath" -ErrorRecord $_ -Continue + Stop-Function -Message "Can't write to $FilePath" -ErrorRecord $_ -Continue } foreach ($sourceprop in $server.Configuration.Properties) { $displayname = $sourceprop.DisplayName $configvalue = $sourceprop.ConfigValue - Add-Content -Path $filepath "EXEC sp_configure '$displayname' , $configvalue;" + Add-Content -Path $FilePath "EXEC sp_configure '$displayname' , $configvalue;" } if ($ShowAdvancedOptions -eq 0) { - Add-Content -Path $filepath "EXEC sp_configure 'show advanced options' , 0;" - Add-Content -Path $filepath "RECONFIGURE WITH OVERRIDE" + Add-Content -Path $FilePath "EXEC sp_configure 'show advanced options' , 0;" + Add-Content -Path $FilePath "RECONFIGURE WITH OVERRIDE" $server.Configuration.ShowAdvancedOptions.ConfigValue = $false $server.Configuration.Alter($true) } - Get-ChildItem -Path $filepath + Get-ChildItem -Path $FilePath } } end { diff --git a/functions/Export-DbaUser.ps1 b/functions/Export-DbaUser.ps1 index 2763dde979..9908a15ce6 100644 --- a/functions/Export-DbaUser.ps1 +++ b/functions/Export-DbaUser.ps1 @@ -17,7 +17,7 @@ function Export-DbaUser { Windows Authentication will be used if SqlCredential is not specified .PARAMETER Database - The database(s) to process - this list is auto-populated from the server. If unspecified, all databases will be processed. + The database(s) to process - this list is auto-populated from the server. If unspecified, all InputObject will be processed. .PARAMETER ExcludeDatabase The database(s) to exclude - this list is auto-populated from the server @@ -29,7 +29,13 @@ function Export-DbaUser { To say to which version the script should be generated. If not specified will use database compatibility level .PARAMETER Path - Specifies the full path of a file to write the script to. + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. + + .PARAMETER InputObject + Allows database objects to be piped in from Get-DbaDatabase .PARAMETER NoClobber Do not overwrite file @@ -37,6 +43,9 @@ function Export-DbaUser { .PARAMETER Append Append to file + .PARAMETER Passthru + Output script to console, useful with | clip + .PARAMETER WhatIf Shows what would happen if the command were to run. No actions are actually performed. @@ -110,38 +119,32 @@ function Export-DbaUser { [CmdletBinding(DefaultParameterSetName = "Default")] [OutputType([String])] param ( - [parameter(Mandatory, ValueFromPipeline)] - [DbaInstanceParameter]$SqlInstance, - [PSCredential] - $SqlCredential, - [object[]]$Database, - [object[]]$ExcludeDatabase, - [object[]]$User, + [parameter(ValueFromPipeline)] + [DbaInstanceParameter[]]$SqlInstance, + [parameter(ValueFromPipeline)] + [Microsoft.SqlServer.Management.Smo.Database[]]$InputObject, + [PSCredential]$SqlCredential, + [string[]]$Database, + [string[]]$ExcludeDatabase, + [string[]]$User, [ValidateSet('SQLServer2000', 'SQLServer2005', 'SQLServer2008/2008R2', 'SQLServer2012', 'SQLServer2014', 'SQLServer2016', 'SQLServer2017')] [string]$DestinationVersion, - [Alias("OutFile", "FilePath", "FileName")] [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [Alias("NoOverwrite")] [switch]$NoClobber, [switch]$Append, + [switch]$Passthru, [switch]$EnableException, [Microsoft.SqlServer.Management.Smo.ScriptingOptions]$ScriptingOptionsObject = $null, [switch]$ExcludeGoBatchSeparator ) begin { - if ($Path) { - if ($Path -notlike "*\*") { $Path = ".\$Path" } - $directory = Split-Path $Path - $exists = Test-Path $directory - - if ($exists -eq $false) { - Stop-Function -Message "Parent directory $directory does not exist" - return - } - } + $null = Test-ExportDirectory -Path $Path - $outsql = @() + $outsql = $script:pathcollection = @() $versions = @{ 'SQLServer2000' = 'Version80' @@ -162,295 +165,261 @@ function Export-DbaUser { 'Version130' = 'SQLServer2016' 'Version140' = 'SQLServer2017' } - } process { if (Test-FunctionInterrupt) { return } - try { - $server = Connect-SqlInstance -SqlInstance $SqlInstance -SqlCredential $SqlCredential - } catch { - Stop-Function -Message "Error occurred while establishing connection to $instance" -Category ConnectionError -ErrorRecord $_ -Target $instance -Continue + foreach ($instance in $SqlInstance) { + $InputObject += Get-DbaDatabase -SqlInstance $instance -SqlCredential $SqlCredential -Database $Database -ExcludeDatabase $ExcludeDatabase } - if (!$database) { - $databases = $server.Databases | Where-Object { $ExcludeDatabase -notcontains $_.Name -and $_.IsAccessible -eq $true } - } else { - if ($pipedatabase) { - $databases = $pipedatabase.name + foreach ($db in $InputObject) { + $FilePath = Get-ExportFilePath -Path $PSBoundParameters.Path -FilePath $PSBoundParameters.FilePath -Type sql -ServerName $db.Parent.Name -Unique + + if ([string]::IsNullOrEmpty($destinationVersion)) { + #Get compatibility level for scripting the objects + $scriptVersion = $db.CompatibilityLevel } else { - $databases = $server.Databases | Where-Object { $_.IsAccessible -eq $true -and ($database -contains $_.Name) } + $scriptVersion = $versions[$destinationVersion] + } + $versionNameDesc = $versionName[$scriptVersion.ToString()] + + #If not passed create new ScriptingOption. Otherwise use the one that was passed + if ($null -eq $ScriptingOptionsObject) { + $ScriptingOptionsObject = New-DbaScriptingOption + $ScriptingOptionsObject.TargetServerVersion = [Microsoft.SqlServer.Management.Smo.SqlServerVersion]::$scriptVersion + $ScriptingOptionsObject.AllowSystemObjects = $false + $ScriptingOptionsObject.IncludeDatabaseRoleMemberships = $true + $ScriptingOptionsObject.ContinueScriptingOnError = $false + $ScriptingOptionsObject.IncludeDatabaseContext = $false + $ScriptingOptionsObject.IncludeIfNotExists = $true } - } - if ($exclude) { - $databases = $databases | Where-Object Name -notin $ExcludeDatabase - } + Write-Message -Level Verbose -Message "Validating users on database $db" - if (@($databases).Count -gt 0) { + if ($User) { + $users = $db.Users | Where-Object { $_.IsSystemObject -eq $false -and $_.Name -notlike "##*" } + } else { + $users = $db.Users + } - #Database Permissions - foreach ($db in $databases) { - if ([string]::IsNullOrEmpty($destinationVersion)) { - #Get compatibility level for scripting the objects - $scriptVersion = $db.CompatibilityLevel - } else { - $scriptVersion = $versions[$destinationVersion] - } - $versionNameDesc = $versionName[$scriptVersion.ToString()] - - #If not passed create new ScriptingOption. Otherwise use the one that was passed - if ($null -eq $ScriptingOptionsObject) { - $ScriptingOptionsObject = New-DbaScriptingOption - $ScriptingOptionsObject.TargetServerVersion = [Microsoft.SqlServer.Management.Smo.SqlServerVersion]::$scriptVersion - $ScriptingOptionsObject.AllowSystemObjects = $false - $ScriptingOptionsObject.IncludeDatabaseRoleMemberships = $true - $ScriptingOptionsObject.ContinueScriptingOnError = $false - $ScriptingOptionsObject.IncludeDatabaseContext = $false - $ScriptingOptionsObject.IncludeIfNotExists = $true - } + # Store roles between users so if we hit the same one we don't create it again + $roles = @() + $stepCounter = 0 + foreach ($dbuser in $users) { + Write-ProgressHelper -TotalSteps $users.Count -Activity "Exporting from $($db.Name)" -StepNumber ($stepCounter++) -Message "Generating script for user $dbuser" + + #setting database + $outsql += "USE [" + $db.Name + "]" + + try { + #Fixed Roles #Dependency Issue. Create Role, before add to role. + foreach ($rolePermission in ($db.Roles | Where-Object { $_.IsFixedRole -eq $false })) { + foreach ($rolePermissionScript in $rolePermission.Script($ScriptingOptionsObject)) { + if ($rolePermission.ToString() -notin $roles) { + $roles += , $rolePermission.ToString() + $outsql += "$($rolePermissionScript.ToString())" + } - Write-Message -Level Output -Message "Validating users on database $db" + } + } - if ($User.Count -eq 0) { - $users = $db.Users | Where-Object { $_.IsSystemObject -eq $false -and $_.Name -notlike "##*" } - } else { - if ($pipedatabase) { - $users = $pipedatabase.name - } else { - $users = $db.Users | Where-Object { $User -contains $_.Name -and $_.IsSystemObject -eq $false -and $_.Name -notlike "##*" } + #Database Create User(s) and add to Role(s) + foreach ($dbUserPermissionScript in $dbuser.Script($ScriptingOptionsObject)) { + if ($dbuserPermissionScript.Contains("sp_addrolemember")) { + $execute = "EXEC " + } else { + $execute = "" + } + $outsql += "$execute$($dbUserPermissionScript.ToString())" } - } - # Store roles between users so if we hit the same one we don't create it again - $roles = @() - if ($users.Count -gt 0) { - foreach ($dbuser in $users) { - Write-Message -Level Output -Message "Generating script for user $dbuser" - - #setting database - $outsql += "USE [" + $db.Name + "]" - - try { - #Fixed Roles #Dependency Issue. Create Role, before add to role. - foreach ($rolePermission in ($db.Roles | Where-Object { $_.IsFixedRole -eq $false })) { - foreach ($rolePermissionScript in $rolePermission.Script($ScriptingOptionsObject)) { - if ($rolePermission.ToString() -notin $roles) { - $roles += , $rolePermission.ToString() - $outsql += "$($rolePermissionScript.ToString())" - } - } - } + #Database Permissions + foreach ($databasePermission in $db.EnumDatabasePermissions() | Where-Object { @("sa", "dbo", "information_schema", "sys") -notcontains $_.Grantee -and $_.Grantee -notlike "##*" -and ($dbuser.Name -contains $_.Grantee) }) { + if ($databasePermission.PermissionState -eq "GrantWithGrant") { + $withGrant = " WITH GRANT OPTION" + $grantDatabasePermission = 'GRANT' + } else { + $withGrant = " " + $grantDatabasePermission = $databasePermission.PermissionState.ToString().ToUpper() + } - #Database Create User(s) and add to Role(s) - foreach ($dbUserPermissionScript in $dbuser.Script($ScriptingOptionsObject)) { - if ($dbuserPermissionScript.Contains("sp_addrolemember")) { - $execute = "EXEC " - } else { - $execute = "" - } - $outsql += "$execute$($dbUserPermissionScript.ToString())" - } + $outsql += "$($grantDatabasePermission) $($databasePermission.PermissionType) TO [$($databasePermission.Grantee)]$withGrant AS [$($databasePermission.Grantor)];" + } - #Database Permissions - foreach ($databasePermission in $db.EnumDatabasePermissions() | Where-Object { @("sa", "dbo", "information_schema", "sys") -notcontains $_.Grantee -and $_.Grantee -notlike "##*" -and ($dbuser.Name -contains $_.Grantee) }) { - if ($databasePermission.PermissionState -eq "GrantWithGrant") { - $withGrant = " WITH GRANT OPTION" - $grantDatabasePermission = 'GRANT' - } else { - $withGrant = " " - $grantDatabasePermission = $databasePermission.PermissionState.ToString().ToUpper() - } + #Database Object Permissions + # NB: This is a bit of a mess for a couple of reasons + # 1. $db.EnumObjectPermissions() doesn't enumerate all object types + # 2. Some (x)Collection types can have EnumObjectPermissions() called + # on them directly (e.g. AssemblyCollection); others can't (e.g. + # ApplicationRoleCollection). Those that can't we iterate the + # collection explicitly and add each object's permission. - $outsql += "$($grantDatabasePermission) $($databasePermission.PermissionType) TO [$($databasePermission.Grantee)]$withGrant AS [$($databasePermission.Grantor)];" - } + $perms = New-Object System.Collections.ArrayList - #Database Object Permissions - # NB: This is a bit of a mess for a couple of reasons - # 1. $db.EnumObjectPermissions() doesn't enumerate all object types - # 2. Some (x)Collection types can have EnumObjectPermissions() called - # on them directly (e.g. AssemblyCollection); others can't (e.g. - # ApplicationRoleCollection). Those that can't we iterate the - # collection explicitly and add each object's permission. + $null = $perms.AddRange($db.EnumObjectPermissions($dbuser.Name)) - $perms = New-Object System.Collections.ArrayList + foreach ($item in $db.ApplicationRoles) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - $null = $perms.AddRange($db.EnumObjectPermissions($dbuser.Name)) + foreach ($item in $db.Assemblies) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.ApplicationRoles) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + foreach ($item in $db.Certificates) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.Assemblies) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + foreach ($item in $db.DatabaseRoles) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.Certificates) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + foreach ($item in $db.FullTextCatalogs) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.DatabaseRoles) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + foreach ($item in $db.FullTextStopLists) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.FullTextCatalogs) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + foreach ($item in $db.SearchPropertyLists) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.FullTextStopLists) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + foreach ($item in $db.ServiceBroker.MessageTypes) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.SearchPropertyLists) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + foreach ($item in $db.RemoteServiceBindings) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.ServiceBroker.MessageTypes) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + foreach ($item in $db.ServiceBroker.Routes) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.RemoteServiceBindings) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + foreach ($item in $db.ServiceBroker.ServiceContracts) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.ServiceBroker.Routes) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + foreach ($item in $db.ServiceBroker.Services) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.ServiceBroker.ServiceContracts) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + if ($scriptVersion -ne "Version80") { + foreach ($item in $db.AsymmetricKeys) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } + } - foreach ($item in $db.ServiceBroker.Services) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } + foreach ($item in $db.SymmetricKeys) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - if ($scriptVersion -ne "Version80") { - foreach ($item in $db.AsymmetricKeys) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) - } - } + foreach ($item in $db.XmlSchemaCollections) { + $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + } - foreach ($item in $db.SymmetricKeys) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + foreach ($objectPermission in $perms | Where-Object { @("sa", "dbo", "information_schema", "sys") -notcontains $_.Grantee -and $_.Grantee -notlike "##*" -and $_.Grantee -eq $dbuser.Name }) { + switch ($objectPermission.ObjectClass) { + 'ApplicationRole' { + $object = 'APPLICATION ROLE::[{0}]' -f $objectPermission.ObjectName } - - foreach ($item in $db.XmlSchemaCollections) { - $null = $perms.AddRange($item.EnumObjectPermissions($dbuser.Name)) + 'AsymmetricKey' { + $object = 'ASYMMETRIC KEY::[{0}]' -f $objectPermission.ObjectName } - - foreach ($objectPermission in $perms | Where-Object { @("sa", "dbo", "information_schema", "sys") -notcontains $_.Grantee -and $_.Grantee -notlike "##*" -and $_.Grantee -eq $dbuser.Name }) { - switch ($objectPermission.ObjectClass) { - 'ApplicationRole' { - $object = 'APPLICATION ROLE::[{0}]' -f $objectPermission.ObjectName - } - 'AsymmetricKey' { - $object = 'ASYMMETRIC KEY::[{0}]' -f $objectPermission.ObjectName - } - 'Certificate' { - $object = 'CERTIFICATE::[{0}]' -f $objectPermission.ObjectName - } - 'DatabaseRole' { - $object = 'ROLE::[{0}]' -f $objectPermission.ObjectName - } - 'FullTextCatalog' { - $object = 'FULLTEXT CATALOG::[{0}]' -f $objectPermission.ObjectName - } - 'FullTextStopList' { - $object = 'FULLTEXT STOPLIST::[{0}]' -f $objectPermission.ObjectName - } - 'MessageType' { - $object = 'Message Type::[{0}]' -f $objectPermission.ObjectName - } - 'ObjectOrColumn' { - if ($scriptVersion -ne "Version80") { - $object = 'OBJECT::[{0}].[{1}]' -f $objectPermission.ObjectSchema, $objectPermission.ObjectName - if ($null -ne $objectPermission.ColumnName) { - $object += '([{0}])' -f $objectPermission.ColumnName - } - } - #At SQL Server 2000 OBJECT did not exists - else { - $object = '[{0}].[{1}]' -f $objectPermission.ObjectSchema, $objectPermission.ObjectName - } - } - 'RemoteServiceBinding' { - $object = 'REMOTE SERVICE BINDING::[{0}]' -f $objectPermission.ObjectName - } - 'Schema' { - $object = 'SCHEMA::[{0}]' -f $objectPermission.ObjectName - } - 'SearchPropertyList' { - $object = 'SEARCH PROPERTY LIST::[{0}]' -f $objectPermission.ObjectName - } - 'Service' { - $object = 'SERVICE::[{0}]' -f $objectPermission.ObjectName - } - 'ServiceContract' { - $object = 'CONTRACT::[{0}]' -f $objectPermission.ObjectName - } - 'ServiceRoute' { - $object = 'ROUTE::[{0}]' -f $objectPermission.ObjectName - } - 'SqlAssembly' { - $object = 'ASSEMBLY::[{0}]' -f $objectPermission.ObjectName - } - 'SymmetricKey' { - $object = 'SYMMETRIC KEY::[{0}]' -f $objectPermission.ObjectName - } - 'User' { - $object = 'USER::[{0}]' -f $objectPermission.ObjectName - } - 'UserDefinedType' { - $object = 'TYPE::[{0}].[{1}]' -f $objectPermission.ObjectSchema, $objectPermission.ObjectName - } - 'XmlNamespace' { - $object = 'XML SCHEMA COLLECTION::[{0}]' -f $objectPermission.ObjectName + 'Certificate' { + $object = 'CERTIFICATE::[{0}]' -f $objectPermission.ObjectName + } + 'DatabaseRole' { + $object = 'ROLE::[{0}]' -f $objectPermission.ObjectName + } + 'FullTextCatalog' { + $object = 'FULLTEXT CATALOG::[{0}]' -f $objectPermission.ObjectName + } + 'FullTextStopList' { + $object = 'FULLTEXT STOPLIST::[{0}]' -f $objectPermission.ObjectName + } + 'MessageType' { + $object = 'Message Type::[{0}]' -f $objectPermission.ObjectName + } + 'ObjectOrColumn' { + if ($scriptVersion -ne "Version80") { + $object = 'OBJECT::[{0}].[{1}]' -f $objectPermission.ObjectSchema, $objectPermission.ObjectName + if ($null -ne $objectPermission.ColumnName) { + $object += '([{0}])' -f $objectPermission.ColumnName } } - - if ($objectPermission.PermissionState -eq "GrantWithGrant") { - $withGrant = " WITH GRANT OPTION" - $grantObjectPermission = 'GRANT' - } else { - $withGrant = " " - $grantObjectPermission = $objectPermission.PermissionState.ToString().ToUpper() + #At SQL Server 2000 OBJECT did not exists + else { + $object = '[{0}].[{1}]' -f $objectPermission.ObjectSchema, $objectPermission.ObjectName } - - $outsql += "$grantObjectPermission $($objectPermission.PermissionType) ON $object TO [$($objectPermission.Grantee)]$withGrant AS [$($objectPermission.Grantor)];" } + 'RemoteServiceBinding' { + $object = 'REMOTE SERVICE BINDING::[{0}]' -f $objectPermission.ObjectName + } + 'Schema' { + $object = 'SCHEMA::[{0}]' -f $objectPermission.ObjectName + } + 'SearchPropertyList' { + $object = 'SEARCH PROPERTY LIST::[{0}]' -f $objectPermission.ObjectName + } + 'Service' { + $object = 'SERVICE::[{0}]' -f $objectPermission.ObjectName + } + 'ServiceContract' { + $object = 'CONTRACT::[{0}]' -f $objectPermission.ObjectName + } + 'ServiceRoute' { + $object = 'ROUTE::[{0}]' -f $objectPermission.ObjectName + } + 'SqlAssembly' { + $object = 'ASSEMBLY::[{0}]' -f $objectPermission.ObjectName + } + 'SymmetricKey' { + $object = 'SYMMETRIC KEY::[{0}]' -f $objectPermission.ObjectName + } + 'User' { + $object = 'USER::[{0}]' -f $objectPermission.ObjectName + } + 'UserDefinedType' { + $object = 'TYPE::[{0}].[{1}]' -f $objectPermission.ObjectSchema, $objectPermission.ObjectName + } + 'XmlNamespace' { + $object = 'XML SCHEMA COLLECTION::[{0}]' -f $objectPermission.ObjectName + } + } - } catch { - Stop-Function -Message "This user may be using functionality from $($versionName[$db.CompatibilityLevel.ToString()]) that does not exist on the destination version ($versionNameDesc)." -Continue -InnerErrorRecord $_ -Target $db + if ($objectPermission.PermissionState -eq "GrantWithGrant") { + $withGrant = " WITH GRANT OPTION" + $grantObjectPermission = 'GRANT' + } else { + $withGrant = " " + $grantObjectPermission = $objectPermission.PermissionState.ToString().ToUpper() } + + $outsql += "$grantObjectPermission $($objectPermission.PermissionType) ON $object TO [$($objectPermission.Grantee)]$withGrant AS [$($objectPermission.Grantor)];" } - } else { - Write-Message -Level Output -Message "No users found on database '$db'" - } - #reset collection - $users = $null + } catch { + Stop-Function -Message "This user may be using functionality from $($versionName[$db.CompatibilityLevel.ToString()]) that does not exist on the destination version ($versionNameDesc)." -Continue -InnerErrorRecord $_ -Target $db + } } - } else { - Write-Message -Level Output -Message "No users found on instance '$server'" - } - } - - end { - if (Test-FunctionInterrupt) { return } - if ($ExcludeGoBatchSeparator) { - $sql = $outsql - } else { - $sql = $outsql -join "`r`nGO`r`n" - #add the final GO - $sql += "`r`nGO" - } - - if ($Path) { - $sql | Out-File -Encoding UTF8 -FilePath $Path -Append:$Append -NoClobber:$NoClobber - } else { - $sql + if ($ExcludeGoBatchSeparator) { + $sql = $outsql + } else { + $sql = $outsql -join "`r`nGO`r`n" + #add the final GO + $sql += "`r`nGO" + } + if (-not $Passthru) { + $sql | Out-File -Encoding UTF8 -FilePath $FilePath -Append:$Append -NoClobber:$NoClobber + } else { + $sql + } } + Get-ChildItem -Path $script:pathcollection.Path } } \ No newline at end of file diff --git a/functions/Export-DbaXECsv.ps1 b/functions/Export-DbaXECsv.ps1 index 7ce4077b60..5bc3ad6fdd 100644 --- a/functions/Export-DbaXECsv.ps1 +++ b/functions/Export-DbaXECsv.ps1 @@ -7,7 +7,10 @@ function Export-DbaXECsv { Exports Extended Events to a CSV file. .PARAMETER Path - Specifies the InputObject to the output CSV file + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER EnableException By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message. @@ -46,9 +49,12 @@ function Export-DbaXECsv { [object[]]$InputObject, [parameter(Mandatory)] [string]$Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport'), + [Alias("OutFile", "FileName")] + [string]$FilePath, [switch]$EnableException ) begin { + $null = Test-ExportDirectory -Path $Path try { Add-Type -Path "$script:PSModuleRoot\bin\XESmartTarget\XESmartTarget.Core.dll" -ErrorAction Stop } catch { @@ -113,28 +119,11 @@ function Export-DbaXECsv { Stop-Function -Continue -Message "$currentfile cannot be accessed from $($env:COMPUTERNAME). Does $whoami have access?" } - if (-not (Test-Path $Path)) { - if ([String]::IsNullOrEmpty([IO.Path]::GetExtension($Path))) { - New-Item $Path -ItemType directory | Out-Null - $outDir = $Path - $outFile = [IO.Path]::GetFileNameWithoutExtension($currentfile) + ".csv" - } else { - $outDir = [IO.Path]::GetDirectoryName($Path) - $outFile = [IO.Path]::GetFileName($Path) - } - } else { - if ((Get-Item $Path) -is [System.IO.DirectoryInfo]) { - $outDir = $Path - $outFile = [IO.Path]::GetFileNameWithoutExtension($currentfile) + ".csv" - } else { - $outDir = [IO.Path]::GetDirectoryName($Path) - $outFile = [IO.Path]::GetFileName($Path) - } - } + $FilePath = Get-ExportFilePath -Path $PSBoundParameters.Path -FilePath $PSBoundParameters.FilePath -Type sql -ServerName $instance $adapter = New-Object XESmartTarget.Core.Utils.XELFileCSVAdapter $adapter.InputFile = $currentfile - $adapter.OutputFile = (Join-Path $outDir $outFile) + $adapter.OutputFile = (Join-Path $outDir $FilePath) try { $adapter.Convert() diff --git a/functions/Export-DbaXESessionTemplate.ps1 b/functions/Export-DbaXESessionTemplate.ps1 index a6b5e15044..99e3e230d7 100644 --- a/functions/Export-DbaXESessionTemplate.ps1 +++ b/functions/Export-DbaXESessionTemplate.ps1 @@ -16,7 +16,10 @@ function Export-DbaXESessionTemplate { The Name of the session(s) to export. .PARAMETER Path - The path to export the file into. Can be .xml or directory. + Specifies the directory where the file or files will be exported. + + .PARAMETER FilePath + Specifies the full file path of the output file. .PARAMETER InputObject Specifies an XE Session output by Get-DbaXESession. @@ -53,12 +56,19 @@ function Export-DbaXESessionTemplate { [DbaInstanceParameter[]]$SqlInstance, [PSCredential]$SqlCredential, [object[]]$Session, + # intentionally left because this is where SSMS defaults [string]$Path = "$home\Documents\SQL Server Management Studio\Templates\XEventTemplates", + [Alias("OutFile", "FileName")] + [string]$FilePath, [Parameter(ValueFromPipeline)] [Microsoft.SqlServer.Management.XEvent.Session[]]$InputObject, [switch]$EnableException ) + begin { + $null = Test-ExportDirectory -Path $Path + } process { + if (Test-FunctionInterrupt) { return } foreach ($instance in $SqlInstance) { try { $InputObject += Get-DbaXESession -SqlInstance $instance -SqlCredential $SqlCredential -Session $Session -EnableException @@ -74,14 +84,12 @@ function Export-DbaXESessionTemplate { Stop-Function -Message "$Path does not exist." -Target $Path } - if ($path.EndsWith(".xml")) { - $filename = $path - } else { - $filename = "$path\$xesname.xml" + if (-not $PSBoundParameters.FilePath) { + $FilePath = "$Path\$xesname.xml" } - Write-Message -Level Verbose -Message "Wrote $xesname to $filename" - [Microsoft.SqlServer.Management.XEvent.XEStore]::SaveSessionToTemplate($xes, $filename, $true) - Get-ChildItem -Path $filename + Write-Message -Level Verbose -Message "Wrote $xesname to $FilePath" + [Microsoft.SqlServer.Management.XEvent.XEStore]::SaveSessionToTemplate($xes, $FilePath, $true) + Get-ChildItem -Path $FilePath } } } \ No newline at end of file diff --git a/internal/functions/Get-ExportFIlePath.ps1 b/internal/functions/Get-ExportFIlePath.ps1 new file mode 100644 index 0000000000..bf72f910de --- /dev/null +++ b/internal/functions/Get-ExportFIlePath.ps1 @@ -0,0 +1,44 @@ +#$FilePath = Get-ExportFilePath -Path $PSBoundParameters.Path -FilePath $PSBoundParameters.FilePath -Type sql -ServerName $instance +function Get-ExportFilePath ($Path, $FilePath, $Type, $ServerName, [switch]$Unique) { + if ($FilePath) { + return ($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($FilePath)) + } + + if (-not $Path) { + $Path = (Get-DbatoolsConfigValue -FullName 'Path.DbatoolsExport') + } + if (-not $Type) { + Write-Warning "You forgot -Type" + return + } + $type = $type.ToLower() + + if (-not $ServerName) { + $ServerName = "sqlinstance" + } + + $ServerName = $ServerName.ToString().Replace('\', '$') + $timenow = (Get-Date -uformat "%m%d%Y%H%M%S") + $caller = (Get-PSCallStack)[1].Command.ToString().Replace("Export-Dba", "").ToLower() + + if ($caller -eq "RepServerSetting") { + $caller = "replication" + } + + $finalpath = Join-DbaPath -Path $Path -Child "$servername-$timenow-$caller.$Type" + + if ($Unique) { + if ($null -eq $script:pathcollection) { + $script:pathcollection = @() + } + if (-not ($script:pathcollection | Where-Object Name -eq $ServerName)) { + $script:pathcollection += [pscustomobject]@{ + Name = $ServerName + Path = ($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($finalpath)) + } + return ($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($finalpath)) + } + } + + return ($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($finalpath)) +} \ No newline at end of file diff --git a/internal/functions/Test-ExportDirectory.ps1 b/internal/functions/Test-ExportDirectory.ps1 new file mode 100644 index 0000000000..c1ffd6af41 --- /dev/null +++ b/internal/functions/Test-ExportDirectory.ps1 @@ -0,0 +1,10 @@ +Function Test-ExportDirectory ($Path) { + if (-not (Test-Path -Path $Path)) { + $null = New-Item -ItemType Directory -Path $Path + } else { + if ((Get-Item $Path -ErrorAction Ignore) -isnot [System.IO.DirectoryInfo]) { + Stop-Function -Message "Path ($Path) must be a directory" + return + } + } +} \ No newline at end of file diff --git a/tests/Export-DbaAvailabilityGroup.Tests.ps1 b/tests/Export-DbaAvailabilityGroup.Tests.ps1 deleted file mode 100644 index a03c3de380..0000000000 --- a/tests/Export-DbaAvailabilityGroup.Tests.ps1 +++ /dev/null @@ -1,78 +0,0 @@ -$CommandName = $MyInvocation.MyCommand.Name.Replace(".Tests.ps1", "") -Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan -. "$PSScriptRoot\constants.ps1" - -Describe "$CommandName Unit Tests" -Tag 'UnitTests' { - Context "Validate parameters" { - [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'AvailabilityGroup', 'ExcludeAvailabilityGroup', 'Path', 'NoClobber', 'EnableException' - $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters - It "Should only contain our specific parameters" { - (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 - } - } -} - -Describe "$commandname Integration Tests" -Tag "IntegrationTests" { - $dbname = "dbatoolsci_agroupdb" - if (-not $env:appveyor) { - BeforeAll { - # $script:instance2 - to make it appear in the proper place on appveyor - Get-DbaProcess -SqlInstance $script:instance3 -Program 'dbatools PowerShell module - dbatools.io' | Stop-DbaProcess -WarningAction SilentlyContinue - $server = Connect-DbaInstance -SqlInstance $script:instance3 - $computername = $server.NetName - $servicename = $server.ServiceName - if ($servicename -eq 'MSSQLSERVER') { - $instancename = "$computername" - } else { - $instancename = "$computername\$servicename" - } - $server.Query("create database $dbname") - $backup = Get-DbaDatabase -SqlInstance $script:instance3 -Database $dbname | Backup-DbaDatabase - $server.Query("IF NOT EXISTS (select * from sys.symmetric_keys where name like '%DatabaseMasterKey%') CREATE MASTER KEY ENCRYPTION BY PASSWORD = ''") - $server.Query("IF EXISTS ( SELECT * FROM sys.tcp_endpoints WHERE name = 'End_Mirroring') DROP ENDPOINT endpoint_mirroring") - $server.Query("CREATE CERTIFICATE dbatoolsci_AGCert WITH SUBJECT = 'AG Certificate'") - $server.Query("CREATE ENDPOINT dbatoolsci_AGEndpoint - STATE = STARTED - AS TCP (LISTENER_PORT = 5022,LISTENER_IP = ALL) - FOR DATABASE_MIRRORING (AUTHENTICATION = CERTIFICATE dbatoolsci_AGCert,ROLE = ALL)") - $server.Query("CREATE AVAILABILITY GROUP dbatoolsci_agroup - WITH (DB_FAILOVER = OFF, DTC_SUPPORT = NONE, CLUSTER_TYPE = NONE) - FOR DATABASE $dbname REPLICA ON N'$instancename' - WITH (ENDPOINT_URL = N'TCP://$computername`:5022', FAILOVER_MODE = MANUAL, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT)") - } - AfterAll { - try { - if ($backup.BackupPath) { Remove-Item -Path $backup.BackupPath -ErrorAction SilentlyContinue } - $server.Query("DROP AVAILABILITY GROUP dbatoolsci_agroup") - Get-DbaDatabase -SqlInstance $script:instance3 -Database $dbname | Remove-DbaDatabase -Confirm:$false - $server.Query("DROP ENDPOINT dbatoolsci_AGEndpoint") - $server.Query("DROP CERTIFICATE dbatoolsci_AGCert") - } catch { - # don't care - } - } - } - Context "exports ags" { - $results = Export-DbaAvailabilityGroup -SqlInstance $script:instance3 - It "returns file objects and one should be the name of the availability group" { - $results.BaseName | Should -Contain 'dbatoolsci_agroup' - } - It "the files it returns should contain the term 'CREATE AVAILABILITY GROUP'" { - $results | Select-String 'CREATE AVAILABILITY GROUP' | Should -Not -Be $null - } - $results | Remove-Item -ErrorAction SilentlyContinue - $results = Export-DbaAvailabilityGroup -SqlInstance $script:instance3 -AvailabilityGroup dbatoolsci_agroup -FilePath C:\temp - It "returns a single result" { - $results.BaseName | Should -Be 'dbatoolsci_agroup' - } - It "the file it returns should contain the term 'CREATE AVAILABILITY GROUP'" { - $results | Select-String 'CREATE AVAILABILITY GROUP' | Should -Not -Be $null - } - It "the file's path should match C:\temp" { - $results.FullName -match 'C:\\temp' | Should -Be $true - } - $results | Remove-Item -ErrorAction SilentlyContinue - } -} -# $script:instance2 - to make it appear in the proper place on appveyor \ No newline at end of file diff --git a/tests/Export-DbaCredential.Tests.ps1 b/tests/Export-DbaCredential.Tests.ps1 index a254732cde..dd3d1dde63 100644 --- a/tests/Export-DbaCredential.Tests.ps1 +++ b/tests/Export-DbaCredential.Tests.ps1 @@ -5,15 +5,94 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'Identity', 'SqlCredential', 'Credential', 'Path', 'ExcludePassword', 'Append', 'InputObject', 'EnableException' + [object[]]$knownParameters = 'SqlInstance', 'Identity', 'SqlCredential', 'Credential', 'Path', 'FilePath', 'ExcludePassword', 'Append', 'InputObject', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 } } } -<# - Integration test should appear below and are custom to the command you are writing. - Read https://github.com/sqlcollaborative/dbatools/blob/development/contributing.md#tests - for more guidence. -#> \ No newline at end of file + + +Describe "$commandname Integration Tests" -Tags "IntegrationTests" { + BeforeAll { + $plaintext = "ReallyT3rrible!" + $password = ConvertTo-SecureString $plaintext -AsPlainText -Force + $null = New-DbaCredential -SqlInstance $script:instance2 -Name dbatoolsci_CaptainAcred -Identity dbatoolsci_CaptainAcred -Password $password + $null = New-DbaCredential -SqlInstance $script:instance2 -Identity dbatoolsci_Hulk -Password $password + $allfiles = @() + } + AfterAll { + try { + (Get-DbaCredential -SqlInstance $script:instance2 -Identity dbatoolsci_CaptainAcred, dbatoolsci_Hulk -ErrorAction Stop -WarningAction SilentlyContinue).Drop() + } catch { } + $null = $allfiles | Remove-Item -ErrorAction Ignore + } + + Context "Should export all credentails" { + $file = Export-DbaCredential -SqlInstance $script:instance2 + $results = Get-Content -Path $file -Raw + $allfiles += $file + It "Should have information" { + $results | Should -Not -Be Null + } + It "Should have all users" { + $results | Should -Match 'CaptainACred|Hulk' + } + It "Should have the password" { + $results | Should -Match 'ReallyT3rrible!' + } + } + + Context "Should export a specific credential" { + $filepath = "$env:USERPROFILE\Documents\dbatoolsci_credential.sql" + $null = Export-DbaCredential -SqlInstance $script:instance2 -Identity 'dbatoolsci_CaptainAcred' -FilePath $filepath + $results = Get-Content -Path $filepath + $allfiles += $filepath + + It "Should have information" { + $results | Should Not Be Null + } + + It "Should only have one credential" { + $results | Should Match 'CaptainAcred' + } + + It "Should have the password" { + $results | Should Match 'ReallyT3rrible!' + } + } + + Context "Should export a specific credential and append it to exisiting export" { + $filepath = "$env:USERPROFILE\Documents\dbatoolsci_credential.sql" + $null = Export-DbaCredential -SqlInstance $script:instance2 -Identity 'dbatoolsci_Hulk' -FilePath $filepath -Append + $results = Get-Content -Path $filepath + + It "Should have information" { + $results | Should Not Be Null + } + + It "Should have multiple credential" { + $results | Should Match 'Hulk|CaptainA' + } + + It "Should have the password" { + $results | Should Match 'ReallyT3rrible!' + } + } + + Context "Should export a specific credential excluding the password" { + $filepath = "$env:USERPROFILE\Documents\temp-credential.sql" + $null = Export-DbaCredential -SqlInstance $script:instance2 -Identity 'dbatoolsci_Hulk' -FilePath $filepath -ExcludePassword + $results = Get-Content -Path $filepath + $allfiles += $filepath + + It "Should have information" { + $results | Should Not Be $null + } + + It "Should not have the password" { + $results | Should Not Match 'ReallyT3rrible!' + } + } +} \ No newline at end of file diff --git a/tests/Export-DbaDacPackage.Tests.ps1 b/tests/Export-DbaDacPackage.Tests.ps1 index 2f28e5b9bd..ca1c28e0dd 100644 --- a/tests/Export-DbaDacPackage.Tests.ps1 +++ b/tests/Export-DbaDacPackage.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Database', 'ExcludeDatabase', 'AllUserDatabases', 'Path', 'DacOption', 'ExtendedParameters', 'ExtendedProperties', 'Type', 'Table', 'EnableException' + [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Database', 'ExcludeDatabase', 'AllUserDatabases', 'Path', 'FilePath', 'DacOption', 'ExtendedParameters', 'ExtendedProperties', 'Type', 'Table', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 @@ -60,7 +60,7 @@ Describe "$commandname Integration Tests" -Tags "IntegrationTests" { It "exports dacpac with a table list" { $relativePath = '.\extract.dacpac' $expectedPath = Join-Path (Get-Item .) 'extract.dacpac' - $results = Export-DbaDacPackage -SqlInstance $script:instance1 -Database $dbname -Path $relativePath -Table example + $results = Export-DbaDacPackage -SqlInstance $script:instance1 -Database $dbname -FilePath $relativePath -Table example $results.Path | Should -Be $expectedPath Test-Path $results.Path | Should -Be $true if (($results).Path) { @@ -100,7 +100,7 @@ Describe "$commandname Integration Tests" -Tags "IntegrationTests" { It "exports bacpac with a table list" { $relativePath = '.\extract.bacpac' $expectedPath = Join-Path (Get-Item .) 'extract.bacpac' - $results = Export-DbaDacPackage -SqlInstance $script:instance1 -Database $dbname -Path $relativePath -Table example -Type Bacpac + $results = Export-DbaDacPackage -SqlInstance $script:instance1 -Database $dbname -FilePath $relativePath -Table example -Type Bacpac $results.Path | Should -Be $expectedPath Test-Path $results.Path | Should -Be $true if (($results).Path) { diff --git a/tests/Export-DbaDbTableData.Tests.ps1 b/tests/Export-DbaDbTableData.Tests.ps1 index c199554e78..63a1545243 100644 --- a/tests/Export-DbaDbTableData.Tests.ps1 +++ b/tests/Export-DbaDbTableData.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'InputObject', 'Path', 'Encoding', 'BatchSeparator', 'NoPrefix', 'Passthru', 'NoClobber', 'Append', 'EnableException' + [object[]]$knownParameters = 'InputObject', 'Path', 'FilePath', 'Encoding', 'BatchSeparator', 'NoPrefix', 'Passthru', 'NoClobber', 'Append', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 diff --git a/tests/Export-DbaDiagnosticQuery.Tests.ps1 b/tests/Export-DbaDiagnosticQuery.Tests.ps1 index c90450b306..fedbbcc148 100644 --- a/tests/Export-DbaDiagnosticQuery.Tests.ps1 +++ b/tests/Export-DbaDiagnosticQuery.Tests.ps1 @@ -15,12 +15,13 @@ Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Describe "$CommandName Integration Tests" -Tags "IntegrationTests" { AfterAll { - (Get-ChildItem "$env:temp\dbatoolsci") | Remove-Item -ErrorAction Ignore + Get-ChildItem "C:\temp\dbatoolsci" -Recurse | Remove-Item -ErrorAction Ignore + Get-Item "C:\temp\dbatoolsci" | Remove-Item -ErrorAction Ignore } Context "Verifying output" { It "exports results to one file and creates directory if required" { - $results = Invoke-DbaDiagnosticQuery -SqlInstance $script:instance2 -QueryName 'Memory Clerk Usage' | Export-DbaDiagnosticQuery -Path "$env:temp\dbatoolsci" - (Get-ChildItem "$env:temp\dbatoolsci").Count | Should Be 1 + $null = Invoke-DbaDiagnosticQuery -SqlInstance $script:instance2 -QueryName 'Memory Clerk Usage' | Export-DbaDiagnosticQuery -Path "C:\temp\dbatoolsci" + (Get-ChildItem "C:\temp\dbatoolsci").Count | Should Be 1 } } } \ No newline at end of file diff --git a/tests/Export-DbaExecutionPlan.Tests.ps1 b/tests/Export-DbaExecutionPlan.Tests.ps1 index ec1f9f62f9..f04b438179 100644 --- a/tests/Export-DbaExecutionPlan.Tests.ps1 +++ b/tests/Export-DbaExecutionPlan.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Database', 'ExcludeDatabase', 'Path', 'SinceCreation', 'SinceLastExecution', 'PipedObject', 'EnableException' + [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Database', 'ExcludeDatabase', 'Path', 'SinceCreation', 'SinceLastExecution', 'InputObject', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 diff --git a/tests/Export-DbaInstance.Tests.ps1 b/tests/Export-DbaInstance.Tests.ps1 index 154c5c89b8..24a911fbe8 100644 --- a/tests/Export-DbaInstance.Tests.ps1 +++ b/tests/Export-DbaInstance.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Credential', 'Path', 'NoRecovery', 'IncludeDbMasterKey', 'Exclude', 'BatchSeparator', 'ScriptingOption', 'EnableException' + [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Credential', 'Path', 'FilePath', 'NoRecovery', 'IncludeDbMasterKey', 'Exclude', 'BatchSeparator', 'ScriptingOption', 'Append', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 @@ -14,21 +14,13 @@ Describe "$CommandName Unit Tests" -Tag 'UnitTests' { } Describe "$commandname Integration Tests" -Tags "IntegrationTests" { AfterAll { - $timenow = (Get-Date -uformat "%m%d%Y%H") - $ExportedItems = Get-ChildItem "$($env:USERPROFILE)\Documents" -Recurse | Where-Object { $_.Name -match "-$timenow\d{4}" -and $_.Attributes -eq 'Directory' } - $null = Remove-Item -Path $($ExportedItems.FullName) -Force -Recurse -ErrorAction SilentlyContinue + $null = Remove-Item -Path $script:results -Force -Recurse -ErrorAction SilentlyContinue } - Context "Should Export all items from an instance" { - $results = Export-DbaInstance -SqlInstance $script:instance2 - It "Should execute with default settings" { - $results | Should Not Be Null - } - } Context "Should exclude some items from an Export" { - $results = Export-DbaInstance -SqlInstance $script:instance2 -Exclude Databases, Logins, SysDbUserObjects, ReplicationSettings + $script:results = Export-DbaInstance -SqlInstance $script:instance2 -Exclude Databases, Logins, SysDbUserObjects, ReplicationSettings, ResourceGovernor It "Should execute with parameters excluding objects" { - $results | Should Not Be Null + $script:results | Should Not Be Null } } } \ No newline at end of file diff --git a/tests/Export-DbaLinkedServer.Tests.ps1 b/tests/Export-DbaLinkedServer.Tests.ps1 index d129e06ae8..8bbc22343c 100644 --- a/tests/Export-DbaLinkedServer.Tests.ps1 +++ b/tests/Export-DbaLinkedServer.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'LinkedServer', 'SqlCredential', 'Credential', 'Path', 'ExcludePassword', 'Append', 'InputObject', 'EnableException' + [object[]]$knownParameters = 'SqlInstance', 'LinkedServer', 'SqlCredential', 'Credential', 'Path', 'FilePath', 'ExcludePassword', 'Append', 'InputObject', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 diff --git a/tests/Export-DbaLogin.Tests.ps1 b/tests/Export-DbaLogin.Tests.ps1 index dea953b35b..29aa8127bc 100644 --- a/tests/Export-DbaLogin.Tests.ps1 +++ b/tests/Export-DbaLogin.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Login', 'ExcludeLogin', 'Database', 'Path', 'NoClobber', 'Append', 'ExcludeDatabases', 'ExcludeJobs', 'EnableException', 'ExcludeGoBatchSeparator', 'DestinationVersion', 'InputObject', 'DefaultDatabase' + [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Login', 'ExcludeLogin', 'Database', 'Path', 'FilePath', 'NoClobber', 'Append', 'ExcludeDatabases', 'ExcludeJobs', 'EnableException', 'ExcludeGoBatchSeparator', 'DestinationVersion', 'InputObject', 'DefaultDatabase' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 @@ -14,7 +14,6 @@ Describe "$CommandName Unit Tests" -Tag 'UnitTests' { } -<# $outputFile = "dbatoolsci_exportdbalogin.sql" Describe "$CommandName Integration Tests" -Tags "IntegrationTests" { @@ -67,19 +66,20 @@ Describe "$CommandName Integration Tests" -Tags "IntegrationTests" { } $output = Export-DbaLogin -SqlInstance $script:instance2 -WarningAction SilentlyContinue - It "Doesn't filter specific databases" { + + It -Skip "Doesn't filter specific databases" { ([regex]::matches($output, 'USE \[.*?\]').Value | Select-Object -Unique).Count | Should BeGreaterThan 0 } - It "Exports disabled logins" { + It -Skip "Exports disabled logins" { [regex]::matches($output, "ALTER LOGIN \[.*?\] DISABLE").Count | Should BeGreaterThan 0 } - It "Exports deny connects" { + It -Skip "Exports deny connects" { [regex]::matches($output, "DENY CONNECT SQL TO \[.*?\]").Count | Should BeGreaterThan 0 } - It "Exports system role memberships" { + It -Skip "Exports system role memberships" { if ($server.VersionMajor -lt 11) { [regex]::matches($output, "EXEC sys.sp_addsrvrolemember @rolename=N'dbcreator', @loginame=N'$login2'").Count | Should BeGreaterThan 0 } else { @@ -88,9 +88,8 @@ Describe "$CommandName Integration Tests" -Tags "IntegrationTests" { } It "Exports to the specified file" { - Export-DbaLogin -SqlInstance $script:instance2 -Path $outputFile -WarningAction SilentlyContinue + Export-DbaLogin -SqlInstance $script:instance2 -FilePath $outputFile -WarningAction SilentlyContinue Test-Path -Path $outputFile | Should Be $true } -} -#> \ No newline at end of file +} \ No newline at end of file diff --git a/tests/Export-DbaPfDataCollectorSetTemplate.Tests.ps1 b/tests/Export-DbaPfDataCollectorSetTemplate.Tests.ps1 index fe09818121..871c448aff 100644 --- a/tests/Export-DbaPfDataCollectorSetTemplate.Tests.ps1 +++ b/tests/Export-DbaPfDataCollectorSetTemplate.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'ComputerName', 'Credential', 'CollectorSet', 'Path', 'InputObject', 'EnableException' + [object[]]$knownParameters = 'ComputerName', 'Credential', 'CollectorSet', 'Path', 'FilePath', 'InputObject', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 diff --git a/tests/Export-DbaRegServer.Tests.ps1 b/tests/Export-DbaRegServer.Tests.ps1 index fc1047390f..31153c3521 100644 --- a/tests/Export-DbaRegServer.Tests.ps1 +++ b/tests/Export-DbaRegServer.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandpath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tags "UnitTests" { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'InputObject', 'Path', 'CredentialPersistenceType', 'EnableException' + [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'InputObject', 'Path', 'FilePath', 'CredentialPersistenceType', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 diff --git a/tests/Export-DbaRepServerSetting.Tests.ps1 b/tests/Export-DbaRepServerSetting.Tests.ps1 index 9cc991bcac..854edbc713 100644 --- a/tests/Export-DbaRepServerSetting.Tests.ps1 +++ b/tests/Export-DbaRepServerSetting.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Path', 'ScriptOption', 'InputObject', 'Encoding', 'Passthru', 'NoClobber', 'Append', 'EnableException' + [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Path', 'FilePath', 'ScriptOption', 'InputObject', 'Encoding', 'Passthru', 'NoClobber', 'Append', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 diff --git a/tests/Export-DbaScript.Tests.ps1 b/tests/Export-DbaScript.Tests.ps1 index 6493ffe6b8..e00c94a0d9 100644 --- a/tests/Export-DbaScript.Tests.ps1 +++ b/tests/Export-DbaScript.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'InputObject', 'ScriptingOptionsObject', 'Path', 'Encoding', 'BatchSeparator', 'NoPrefix', 'Passthru', 'NoClobber', 'Append', 'EnableException' + [object[]]$knownParameters = 'InputObject', 'ScriptingOptionsObject', 'Path', 'FilePath', 'Encoding', 'BatchSeparator', 'NoPrefix', 'Passthru', 'NoClobber', 'Append', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 diff --git a/tests/Export-DbaSpConfigure.Tests.ps1 b/tests/Export-DbaSpConfigure.Tests.ps1 index 7d91cb1859..e70ce42700 100644 --- a/tests/Export-DbaSpConfigure.Tests.ps1 +++ b/tests/Export-DbaSpConfigure.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Path', 'EnableException' + [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Path', 'FilePath', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 diff --git a/tests/Export-DbaUser.Tests.ps1 b/tests/Export-DbaUser.Tests.ps1 index 49701535db..87000ebe88 100644 --- a/tests/Export-DbaUser.Tests.ps1 +++ b/tests/Export-DbaUser.Tests.ps1 @@ -1,12 +1,12 @@ $CommandName = $MyInvocation.MyCommand.Name.Replace(".Tests.ps1", "") Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan . "$PSScriptRoot\constants.ps1" -$outputFile = "$env:temp\dbatoolsci_user.sql" +$outputFile = "C:\temp\dbatoolsci_user.sql" Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Database', 'ExcludeDatabase', 'User', 'DestinationVersion', 'Path', 'NoClobber', 'Append', 'EnableException', 'ScriptingOptionsObject', 'ExcludeGoBatchSeparator' + [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Database', 'ExcludeDatabase', 'User', 'DestinationVersion', 'Path', 'FilePath', 'InputObject', 'NoClobber', 'Append', 'EnableException', 'ScriptingOptionsObject', 'ExcludeGoBatchSeparator', 'Passthru' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 @@ -38,7 +38,7 @@ Describe "$commandname Integration Tests" -Tags "IntegrationTests" { Context "Check if output file was created" { if (Get-DbaDbUser -SqlInstance $script:instance1 -Database $dbname | Where-Object Name -eq $user) { - $results = Export-DbaUser -SqlInstance $script:instance1 -Database $dbname -User $user -FilePath $outputFile + $null = Export-DbaUser -SqlInstance $script:instance1 -Database $dbname -User $user -FilePath $outputFile It "Exports results to one sql file" { (Get-ChildItem $outputFile).Count | Should Be 1 } diff --git a/tests/Export-DbaXECsv.Tests.ps1 b/tests/Export-DbaXECsv.Tests.ps1 index 062eccc73f..c8dd02060a 100644 --- a/tests/Export-DbaXECsv.Tests.ps1 +++ b/tests/Export-DbaXECsv.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'InputObject', 'Path', 'EnableException' + [object[]]$knownParameters = 'InputObject', 'Path', 'FilePath', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 diff --git a/tests/Export-DbaXESessionTemplate.Tests.ps1 b/tests/Export-DbaXESessionTemplate.Tests.ps1 index d867667d67..27fb416f19 100644 --- a/tests/Export-DbaXESessionTemplate.Tests.ps1 +++ b/tests/Export-DbaXESessionTemplate.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Session', 'Path', 'InputObject', 'EnableException' + [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Session', 'Path', 'FilePath', 'InputObject', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0