diff --git a/allcommands.zip b/allcommands.zip index ab410c5894..759ce9b878 100644 Binary files a/allcommands.zip and b/allcommands.zip differ diff --git a/bin/dbatools-index.json.REMOVED.git-id b/bin/dbatools-index.json.REMOVED.git-id index b29052324c..eff17d71e0 100644 --- a/bin/dbatools-index.json.REMOVED.git-id +++ b/bin/dbatools-index.json.REMOVED.git-id @@ -1 +1 @@ -0460cb948613c5cac307ac21b7e20e946c81cc17 \ No newline at end of file +7509d6d06907f7baf4840d49bce50fe1ce945824 \ No newline at end of file diff --git a/changelog.md b/changelog.md index da33ad7e60..b8225f5ef6 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.9.720] - 2018-12-16 +### Fixed +* Enhanced outputs of Invoke-DbaDbDataMasking +* Save-DbaDiagnosticQuery to work with lightly malformed links + ## [0.9.719] - 2018-12-15 ### Added * Piping to Get-DbaDbSpace diff --git a/dbatools.psd1 b/dbatools.psd1 index ad8414094c..24c9767e63 100644 --- a/dbatools.psd1 +++ b/dbatools.psd1 @@ -11,7 +11,7 @@ RootModule = 'dbatools.psm1' # Version number of this module. - ModuleVersion = '0.9.719' + ModuleVersion = '0.9.720' # ID used to uniquely identify this module GUID = '9d139310-ce45-41ce-8e8b-d76335aa1789' diff --git a/functions/Invoke-DbaDbDataMasking.ps1 b/functions/Invoke-DbaDbDataMasking.ps1 index 3253136664..f27afb609f 100644 --- a/functions/Invoke-DbaDbDataMasking.ps1 +++ b/functions/Invoke-DbaDbDataMasking.ps1 @@ -53,6 +53,9 @@ function Invoke-DbaDbDataMasking { Useful for adhoc updates and testing, otherwise, the config file should be used. + .PARAMETER ExactLength + Mask string values to the same length. So 'Tate' will be replaced with 4 random characters. + .PARAMETER Force Forcefully execute commands when needed @@ -117,6 +120,7 @@ function Invoke-DbaDbDataMasking { [string[]]$ExcludeColumn, [string]$Query, [int]$MaxValue, + [switch]$ExactLength, [switch]$EnableException ) begin { @@ -147,12 +151,11 @@ function Invoke-DbaDbDataMasking { return } } - - if ($Table) { - $tables = $tables | Where-Object Name -in $Table - } - + foreach ($tabletest in $tables.Tables) { + if ($Table -and $tabletest.Name -notin $Table) { + continue + } foreach ($columntest in $tabletest.Columns) { if ($columntest.ColumnType -in 'hierarchyid', 'geography', 'xml' -and $columntest.Name -notin $Column) { Stop-Function -Message "$($columntest.ColumnType) is not supported, please remove the column $($columntest.Name) from the $($tabletest.Name) table" -Target $tables @@ -174,7 +177,7 @@ function Invoke-DbaDbDataMasking { foreach ($db in (Get-DbaDatabase -SqlInstance $server -Database $Database)) { $stepcounter = 0 foreach ($tableobject in $tables.Tables) { - if ($tableobject.Name -in $ExcludeTable) { + if ($tableobject.Name -in $ExcludeTable -or ($Table -and $tableobject.Name -notin $Table)) { Write-Message -Level Verbose -Message "Skipping $($tableobject.Name) because it is explicitly excluded" continue } @@ -189,9 +192,10 @@ function Invoke-DbaDbDataMasking { $data = $db.Query($query) | ConvertTo-DbaDataTable } catch { - Stop-Function -Message "Something went wrong retrieving the data from table $($tableobject.Name)" -Target $Database + Stop-Function -Message "Failure retrieving the data from table $($tableobject.Name)" -Target $Database -ErrorRecord $_ -Continue } + $elapsed = [System.Diagnostics.Stopwatch]::StartNew() $tablecolumns = $tableobject.Columns if ($Column) { @@ -297,6 +301,13 @@ function Invoke-DbaDbDataMasking { 'uniqueidentifier' { $faker.System.Random.Guid().Guid } + 'userdefineddatatype' { + if ($columnobject.MaxValue -eq 1) { + $faker.System.Random.Bool() + } else { + $null + } + } default { $null } @@ -335,6 +346,11 @@ function Invoke-DbaDbDataMasking { if ($max -eq -1) { $max = 1024 } + + if ($columnobject.SubType -eq "String" -and (Test-Bound -ParameterName ExactLength)) { + $max = ($row.$($columnobject.Name)).Length + } + if ($columnobject.ColumnType -eq 'xml') { $null } else { @@ -345,6 +361,9 @@ function Invoke-DbaDbDataMasking { if ($max -eq -1) { $max = 1024 } + if ((Test-Bound -ParameterName ExactLength)) { + $max = ($row.$($columnobject.Name)).ToString().Length + } $faker.Random.String2($max, $charstring) } } @@ -387,6 +406,8 @@ function Invoke-DbaDbDataMasking { Schema = $tableobject.Schema Table = $tableobject.Name Columns = $tableobject.Columns.Name + Rows = $($data.Rows.Count) + Elapsed = [prettytimespan]$elapsed.Elapsed Status = "Masked" } } diff --git a/functions/New-DbaDbMaskingConfig.ps1 b/functions/New-DbaDbMaskingConfig.ps1 index 5cb1e656ea..d272ae15c5 100644 --- a/functions/New-DbaDbMaskingConfig.ps1 +++ b/functions/New-DbaDbMaskingConfig.ps1 @@ -308,6 +308,23 @@ function New-DbaDbMaskingConfig { $subType = "Number" $MaxValue = 255 } + "varbinary" { + $subType = "Byte" + $MaxValue = $columnLength + } + "varbinary" { + $subType = "Byte" + $MaxValue = $columnLength + } + "userdefineddatatype" { + if ($columnLength -eq 1) { + $subType = "Bool" + $MaxValue = $columnLength + } else { + $subType = "String" + $MaxValue = $columnLength + } + } default { $subType = "String" $MaxValue = $columnLength diff --git a/functions/Save-DbaDiagnosticQueryScript.ps1 b/functions/Save-DbaDiagnosticQueryScript.ps1 index d39c3a28da..4328988210 100644 --- a/functions/Save-DbaDiagnosticQueryScript.ps1 +++ b/functions/Save-DbaDiagnosticQueryScript.ps1 @@ -66,7 +66,7 @@ function Save-DbaDiagnosticQueryScript { $glenberryrss = "http://www.sqlskills.com/blogs/glenn/feed/" $glenberrysql = @() - Write-Message -Level Output -Message "Downloading RSS Feed" + Write-Message -Level Verbose -Message "Downloading RSS Feed" $rss = [xml](get-webdata -uri $glenberryrss) $Feed = $rss.rss.Channel @@ -90,12 +90,15 @@ function Save-DbaDiagnosticQueryScript { break } } - Write-Message -Level Output -Message "Found $($glenberrysql.Count) documents to download" + Write-Message -Level Verbose -Message "Found $($glenberrysql.Count) documents to download" foreach ($doc in $glenberrysql) { try { - Write-Message -Level Output -Message "Downloading $($doc.URL)" + $link = $doc.URL.ToString().Replace('dl=0', 'dl=1') + Write-Message -Level Verbose -Message "Downloading $link)" + Write-ProgressHelper -Activity "Downloading Glenn Berry's most recent DMVs" -ExcludePercent -Message "Downloading $link" -StepNumber 1 $filename = "{0}\SQLServerDiagnosticQueries_{1}_{2}.sql" -f $Path, $doc.SQLVersion, "$($doc.FileYear)$($doc.FileMonth)" - Invoke-TlsWebRequest -Uri $doc.URL.ToString().Replace('dl\=0','dl\=1') -OutFile $filename -ErrorAction Stop + Invoke-TlsWebRequest -Uri $link -OutFile $filename -ErrorAction Stop + Get-ChildItem -Path $filename } catch { Stop-Function -Message "Requesting and writing file failed: $_" -Target $filename -ErrorRecord $_ return diff --git a/functions/Set-DbaSpn.ps1 b/functions/Set-DbaSpn.ps1 index 610c4c89a0..49d3ac0627 100644 --- a/functions/Set-DbaSpn.ps1 +++ b/functions/Set-DbaSpn.ps1 @@ -44,19 +44,19 @@ function Set-DbaSpn { https://dbatools.io/Set-DbaSpn .EXAMPLE - PS C:\> Set-DbaSpn -SPN MSSQLSvc\SQLSERVERA.domain.something -ServiceAccount domain\account - PS C:\> Set-DbaSpn -SPN MSSQLSvc\SQLSERVERA.domain.something -ServiceAccount domain\account -EnableException + PS C:\> Set-DbaSpn -SPN MSSQLSvc/SQLSERVERA.domain.something -ServiceAccount domain\account + PS C:\> Set-DbaSpn -SPN MSSQLSvc/SQLSERVERA.domain.something -ServiceAccount domain\account -EnableException Connects to Active Directory and adds a provided SPN to the given account. Connects to Active Directory and adds a provided SPN to the given account, suppressing all error messages and throw exceptions that can be caught instead .EXAMPLE - PS C:\> Set-DbaSpn -SPN MSSQLSvc\SQLSERVERA.domain.something -ServiceAccount domain\account -Credential ad\sqldba + PS C:\> Set-DbaSpn -SPN MSSQLSvc/SQLSERVERA.domain.something -ServiceAccount domain\account -Credential ad\sqldba Connects to Active Directory and adds a provided SPN to the given account. Uses alternative account to connect to AD. .EXAMPLE - PS C:\> Set-DbaSpn -SPN MSSQLSvc\SQLSERVERA.domain.something -ServiceAccount domain\account -NoDelegation + PS C:\> Set-DbaSpn -SPN MSSQLSvc/SQLSERVERA.domain.something -ServiceAccount domain\account -NoDelegation Connects to Active Directory and adds a provided SPN to the given account, without the delegation. diff --git a/tests/Invoke-DbaDbDataMasking.Tests.ps1 b/tests/Invoke-DbaDbDataMasking.Tests.ps1 index 4cc1eb5a23..be6dacc79d 100644 --- a/tests/Invoke-DbaDbDataMasking.Tests.ps1 +++ b/tests/Invoke-DbaDbDataMasking.Tests.ps1 @@ -6,7 +6,7 @@ Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { $defaultParamCount = 13 [object[]]$params = (Get-ChildItem function:\Invoke-DbaDbDataMasking).Parameters.Keys - $knownParameters = 'SqlInstance', 'SqlCredential', 'Database', 'FilePath', 'Locale', 'CharacterString', 'Table', 'Column', 'ExcludeTable', 'ExcludeColumn', 'Query', 'MaxValue', 'EnableException' + $knownParameters = 'SqlInstance', 'SqlCredential', 'Database', 'FilePath', 'Locale', 'CharacterString', 'Table', 'Column', 'ExcludeTable', 'ExcludeColumn', 'Query', 'MaxValue', 'EnableException','ExactLength' It "Should contain our specific parameters" { ( (Compare-Object -ReferenceObject $knownParameters -DifferenceObject $params -IncludeEqual | Where-Object SideIndicator -eq "==").Count ) | Should Be $knownParameters.Count } diff --git a/tests/pester.groups.ps1 b/tests/pester.groups.ps1 index cc2f9dc867..f2a4096d63 100644 --- a/tests/pester.groups.ps1 +++ b/tests/pester.groups.ps1 @@ -50,7 +50,8 @@ $TestsRunGroups = @{ 'Test-DbaDbVirtualLogFile', 'Test-DbaAgentJobOwner', 'Resume-DbaAgDbDataMovement', - 'Get-DbaDbMasterKey' + 'Get-DbaDbMasterKey', + 'Test-DbaJobOwner' ) # do not run everywhere "disabled" = @()