From 2c772f8d2b26fdc842841c54498be2a8a3b6add9 Mon Sep 17 00:00:00 2001 From: reitse thuis Date: Fri, 7 Jun 2019 23:13:52 +0200 Subject: [PATCH 1/5] Create Get-DatabaseDiskFreeSpace.ps1 Hopefully this helps with issue 320 --- functions/Get-DatabaseDiskFreeSpace.ps1 | 100 ++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 functions/Get-DatabaseDiskFreeSpace.ps1 diff --git a/functions/Get-DatabaseDiskFreeSpace.ps1 b/functions/Get-DatabaseDiskFreeSpace.ps1 new file mode 100644 index 00000000..5c1c2bf3 --- /dev/null +++ b/functions/Get-DatabaseDiskFreeSpace.ps1 @@ -0,0 +1,100 @@ +function Get-DatabaseDiskFreeSpace { + <# + .SYNOPSIS + Returns if there is enough diskspace for the instance to grow for one cycle. + + .DESCRIPTION + Returns if there is enough diskspace for the instance to grow for one cycle. + The checks is disk based, so the check will be done for each disk where the databases stores files. + + .NOTES + Tags: Database, FileSize, FileGrowth + Author: Reitse Eskens (@2meterDBA) + + .PARAMETER SqlInstance + The Instance for which you want to perform your check + + .PARAMETER SqlCredential + Credentials to connect to the SQL Server instance if the calling user doesn't have permission + + .EXAMPLE + Get-DatabaseDiskFreeSpace -SqlInstance sql2016 + #> + +[CmdletBinding()] + +param ( + [parameter(ValueFromPipeline)] + [DbaInstanceParameter[]]$SqlInstance, + [PSCredential]$SqlCredential + ) + + +begin { +<# + Step one. Get de free diskspace from the disks where Sql Server is parking it's files. + The line will get the data from the chosen instance. Next the result is filtered down to just the drive letter for the summation later on. + The -unique is used to limit the results. We get a result line for each database file, but all we need is a drive and the free space. + +#> + +$DiskFreeSpace = Get-DbaDbFile -SqlInstance REITSE-PC\VANTAGE | SELECT @{label='DriveLetter';Expression={$_.PhysicalName.substring(0,3)}}, VolumeFreeSpace |Sort-Object -Property Driveletter -Unique + +<# + Step two. Determine per drive letter how much growth can be expected. + Same concept as the first step, but now we're looking at the file growth. +#> + +$FileGrowth = Get-DbaDbFile -SqlInstance REITSE-PC\VANTAGE | SELECT @{label='DriveLetter';Expression={$_.PhysicalName.substring(0,3)}}, NextGrowthEventSize + +<# + Step three, summation of the disk growth +#> + + +$calc = $FileGrowth | Group-Object -Property Driveletter | ForEach-Object -Process { + $Sum = $_.group | measure -Sum -Property NextGrowthEventSize + [pscustomobject]@{DriveLetter=$_.Name ; value = $Sum.Sum} +} + +<# + Step three and a bit, because the summation results in something else than GB, the result is rebuilt to gigabytes +#> + + +$CalcInGB = $calc | select DriveLetter, @{name="GrowthInGB" ; Expression={[math]::Round($_.value/1GB, 2)}} + +<# + Now for the interesting part. Time to compare the results! + For each line in the disk free space results, the expected growth will be checked. + If the drives are the same, the comparison will take place and the result will be shown. +#> + + +$DiskFreeSpace | ForEach-Object -Process { + if($_.DriveLetter -cin $CalcInGB.DriveLetter) + { + $localDisk = $_.DriveLetter + $localFileSize = $_.VolumeFreeSpace + $CalcInGB | ForEach-Object -Process { + If($_.DriveLetter -eq $localDisk) + { + if($_.GrowthInGB -ge $localFileSize ) + { + Write-Host $localDisk 'Don't panic, don't Panic. Time to grow the this disk mr Mainwairing' + } + else + { + Write-Host $localDisk 'Fall in chaps, if you please... yes yes yes you look very smart' + } + + } + } + } + else + { + Write-Host $_.DriveLetter 'Pike! You stupid Boy!' + } + } + } +} \ No newline at end of file From ddfeb1a50c3b7609345799620abc61d6d112f0b2 Mon Sep 17 00:00:00 2001 From: reitse thuis Date: Fri, 7 Jun 2019 23:31:47 +0200 Subject: [PATCH 2/5] Update Get-DatabaseDiskFreeSpace.ps1 Cleaned up the code --- functions/Get-DatabaseDiskFreeSpace.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/functions/Get-DatabaseDiskFreeSpace.ps1 b/functions/Get-DatabaseDiskFreeSpace.ps1 index 5c1c2bf3..03afe688 100644 --- a/functions/Get-DatabaseDiskFreeSpace.ps1 +++ b/functions/Get-DatabaseDiskFreeSpace.ps1 @@ -38,14 +38,14 @@ begin { #> -$DiskFreeSpace = Get-DbaDbFile -SqlInstance REITSE-PC\VANTAGE | SELECT @{label='DriveLetter';Expression={$_.PhysicalName.substring(0,3)}}, VolumeFreeSpace |Sort-Object -Property Driveletter -Unique +$DiskFreeSpace = Get-DbaDbFile -SqlInstance $SqlInstance | Select-Object @{label='DriveLetter';Expression={$_.PhysicalName.substring(0,3)}}, VolumeFreeSpace |Sort-Object -Property Driveletter -Unique <# Step two. Determine per drive letter how much growth can be expected. Same concept as the first step, but now we're looking at the file growth. #> -$FileGrowth = Get-DbaDbFile -SqlInstance REITSE-PC\VANTAGE | SELECT @{label='DriveLetter';Expression={$_.PhysicalName.substring(0,3)}}, NextGrowthEventSize +$FileGrowth = Get-DbaDbFile -SqlInstance $SqlInstance | Select-Object @{label='DriveLetter';Expression={$_.PhysicalName.substring(0,3)}}, NextGrowthEventSize <# Step three, summation of the disk growth @@ -53,7 +53,7 @@ $FileGrowth = Get-DbaDbFile -SqlInstance REITSE-PC\VANTAGE | SELECT @{label='Dri $calc = $FileGrowth | Group-Object -Property Driveletter | ForEach-Object -Process { - $Sum = $_.group | measure -Sum -Property NextGrowthEventSize + $Sum = $_.group | Measure-Object -Sum -Property NextGrowthEventSize [pscustomobject]@{DriveLetter=$_.Name ; value = $Sum.Sum} } @@ -62,7 +62,7 @@ $calc = $FileGrowth | Group-Object -Property Driveletter | ForEach-Object -Proce #> -$CalcInGB = $calc | select DriveLetter, @{name="GrowthInGB" ; Expression={[math]::Round($_.value/1GB, 2)}} +$CalcInGB = $calc | Select-Object DriveLetter, @{name="GrowthInGB" ; Expression={[math]::Round($_.value/1GB, 2)}} <# Now for the interesting part. Time to compare the results! From d08933e61203132bb07eb39ddc5647ef59438300 Mon Sep 17 00:00:00 2001 From: Reitse HP G4 Date: Mon, 17 Jun 2019 21:14:20 +0200 Subject: [PATCH 3/5] Update Get-DatabaseDiskFreeSpace.ps1 Made some progress with the helpfull comments of Sean and Rob. The last change is somewhat iffy. I've created the custom object but do you want it to write to the host or do you want to write it to a file? --- functions/Get-DatabaseDiskFreeSpace.ps1 | 40 ++++++++++++++++++------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/functions/Get-DatabaseDiskFreeSpace.ps1 b/functions/Get-DatabaseDiskFreeSpace.ps1 index 03afe688..2755cfad 100644 --- a/functions/Get-DatabaseDiskFreeSpace.ps1 +++ b/functions/Get-DatabaseDiskFreeSpace.ps1 @@ -32,21 +32,36 @@ param ( begin { <# - Step one. Get de free diskspace from the disks where Sql Server is parking it's files. + Step one. Get the free diskspace from the disks where Sql Server is parking it's files. The line will get the data from the chosen instance. Next the result is filtered down to just the drive letter for the summation later on. The -unique is used to limit the results. We get a result line for each database file, but all we need is a drive and the free space. #> - -$DiskFreeSpace = Get-DbaDbFile -SqlInstance $SqlInstance | Select-Object @{label='DriveLetter';Expression={$_.PhysicalName.substring(0,3)}}, VolumeFreeSpace |Sort-Object -Property Driveletter -Unique - +try { + $DiskFreeSpace = Get-DbaDbFile -SqlInstance $SqlInstance | Select-Object @{label='DriveLetter';Expression={$_.PhysicalName.substring(0,3)}}, VolumeFreeSpace, @{label='ComputerName';Expression={$env:COMPUTERNAME}} |Sort-Object -Property Driveletter -Unique +} +catch { + Stop-PSFFunction -Message "There was a problem getting the free diskspace" -ErrorRecord $psitem +} +finally { + Write-PSFMessage -Level Warning -Message "Execution was cancelled!" + Pop-Location +} <# Step two. Determine per drive letter how much growth can be expected. Same concept as the first step, but now we're looking at the file growth. #> -$FileGrowth = Get-DbaDbFile -SqlInstance $SqlInstance | Select-Object @{label='DriveLetter';Expression={$_.PhysicalName.substring(0,3)}}, NextGrowthEventSize - +try { + $FileGrowth = Get-DbaDbFile -SqlInstance $SqlInstance | Select-Object @{label='DriveLetter';Expression={$_.PhysicalName.substring(0,3)}}, NextGrowthEventSize +} +catch { + Stop-PSFFunction -Message "There was a problem getting the disk growth data" -ErrorRecord $psitem +} +finally { + Write-PSFMessage -Level Warning -Message "Execution was cancelled!" + Pop-Location +} <# Step three, summation of the disk growth #> @@ -54,7 +69,7 @@ $FileGrowth = Get-DbaDbFile -SqlInstance $SqlInstance | Select-Object @{label='D $calc = $FileGrowth | Group-Object -Property Driveletter | ForEach-Object -Process { $Sum = $_.group | Measure-Object -Sum -Property NextGrowthEventSize - [pscustomobject]@{DriveLetter=$_.Name ; value = $Sum.Sum} + [pscustomobject]@{DriveLetter=$_.Name ; Value = [SqlCollaborative.Dbatools.Utility.Size]::new($Sum.sum)} } <# @@ -62,8 +77,8 @@ $calc = $FileGrowth | Group-Object -Property Driveletter | ForEach-Object -Proce #> -$CalcInGB = $calc | Select-Object DriveLetter, @{name="GrowthInGB" ; Expression={[math]::Round($_.value/1GB, 2)}} - +# $CalcInGB = $calc | Select-Object DriveLetter, @{name="GrowthInGB" ; Expression={[math]::Round($_.value/1GB, 2)}} +# The above step is still alive for regression testing. <# Now for the interesting part. Time to compare the results! For each line in the disk free space results, the expected growth will be checked. @@ -72,20 +87,23 @@ $CalcInGB = $calc | Select-Object DriveLetter, @{name="GrowthInGB" ; Expression= $DiskFreeSpace | ForEach-Object -Process { - if($_.DriveLetter -cin $CalcInGB.DriveLetter) + if($_.DriveLetter -cin $Calc.DriveLetter) { $localDisk = $_.DriveLetter $localFileSize = $_.VolumeFreeSpace - $CalcInGB | ForEach-Object -Process { + $computerName = $_.ComputerName + $Calc | ForEach-Object -Process { If($_.DriveLetter -eq $localDisk) { if($_.GrowthInGB -ge $localFileSize ) { Write-Host $localDisk 'Don't panic, don't Panic. Time to grow the this disk mr Mainwairing' + [PSCustomObject]@{Computer = $computerName ; SQLInstance = $SqlInstance ; DiskFreeSpace = $localFileSize ; Growth = $_.GrowthInGB ; GrowthAchievable = 'false'} } else { Write-Host $localDisk 'Fall in chaps, if you please... yes yes yes you look very smart' + [PSCustomObject]@{Computer = $computerName ; SQLInstance = $SqlInstance ; DiskFreeSpace = $localFileSize ; Growth = $_.GrowthInGB ; GrowthAchievable = 'true'} } } From e9977c7170e042c45e8fd715078bfa9dfa12c0f5 Mon Sep 17 00:00:00 2001 From: reitse thuis Date: Mon, 17 Jun 2019 22:12:17 +0200 Subject: [PATCH 4/5] Update Get-DatabaseDiskFreeSpace.ps1 Fixed a little bug with a wrong column name in the output. Excluded the finally from the try catch. It got there every time for no apparent reason. --- functions/Get-DatabaseDiskFreeSpace.ps1 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/functions/Get-DatabaseDiskFreeSpace.ps1 b/functions/Get-DatabaseDiskFreeSpace.ps1 index 2755cfad..2720f19d 100644 --- a/functions/Get-DatabaseDiskFreeSpace.ps1 +++ b/functions/Get-DatabaseDiskFreeSpace.ps1 @@ -43,10 +43,10 @@ try { catch { Stop-PSFFunction -Message "There was a problem getting the free diskspace" -ErrorRecord $psitem } -finally { - Write-PSFMessage -Level Warning -Message "Execution was cancelled!" - Pop-Location -} +#finally { +# Write-PSFMessage -Level Warning -Message "Execution was cancelled!" +# Pop-Location +#} <# Step two. Determine per drive letter how much growth can be expected. Same concept as the first step, but now we're looking at the file growth. @@ -58,10 +58,10 @@ try { catch { Stop-PSFFunction -Message "There was a problem getting the disk growth data" -ErrorRecord $psitem } -finally { - Write-PSFMessage -Level Warning -Message "Execution was cancelled!" - Pop-Location -} +#finally { +# Write-PSFMessage -Level Warning -Message "Execution was cancelled!" +# Pop-Location +#} <# Step three, summation of the disk growth #> @@ -98,12 +98,12 @@ $DiskFreeSpace | ForEach-Object -Process { if($_.GrowthInGB -ge $localFileSize ) { Write-Host $localDisk 'Don't panic, don't Panic. Time to grow the this disk mr Mainwairing' - [PSCustomObject]@{Computer = $computerName ; SQLInstance = $SqlInstance ; DiskFreeSpace = $localFileSize ; Growth = $_.GrowthInGB ; GrowthAchievable = 'false'} + [PSCustomObject]@{Computer = $computerName ; SQLInstance = $SqlInstance ; DiskFreeSpace = $localFileSize ; Growth = $_.Value ; GrowthAchievable = 'false'} } else { Write-Host $localDisk 'Fall in chaps, if you please... yes yes yes you look very smart' - [PSCustomObject]@{Computer = $computerName ; SQLInstance = $SqlInstance ; DiskFreeSpace = $localFileSize ; Growth = $_.GrowthInGB ; GrowthAchievable = 'true'} + [PSCustomObject]@{Computer = $computerName ; SQLInstance = $SqlInstance ; DiskFreeSpace = $localFileSize ; Growth = $_.Value ; GrowthAchievable = 'true'} } } From 6780cf340e136bb23eedbd5fce2dc5b813da7175 Mon Sep 17 00:00:00 2001 From: reitse thuis Date: Sun, 18 Aug 2019 14:32:31 +0200 Subject: [PATCH 5/5] Added Assertion Assert-DBGrowthEvent added to the InstanceAssertions. Removed the commandline output in the GetDatabaseDiskFreeSpace that has been replaced with the custom function. --- functions/Get-DatabaseDiskFreeSpace.ps1 | 2 -- internal/assertions/Instance.Assertions.ps1 | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/functions/Get-DatabaseDiskFreeSpace.ps1 b/functions/Get-DatabaseDiskFreeSpace.ps1 index 2720f19d..07cd8fc1 100644 --- a/functions/Get-DatabaseDiskFreeSpace.ps1 +++ b/functions/Get-DatabaseDiskFreeSpace.ps1 @@ -97,12 +97,10 @@ $DiskFreeSpace | ForEach-Object -Process { { if($_.GrowthInGB -ge $localFileSize ) { - Write-Host $localDisk 'Don't panic, don't Panic. Time to grow the this disk mr Mainwairing' [PSCustomObject]@{Computer = $computerName ; SQLInstance = $SqlInstance ; DiskFreeSpace = $localFileSize ; Growth = $_.Value ; GrowthAchievable = 'false'} } else { - Write-Host $localDisk 'Fall in chaps, if you please... yes yes yes you look very smart' [PSCustomObject]@{Computer = $computerName ; SQLInstance = $SqlInstance ; DiskFreeSpace = $localFileSize ; Growth = $_.Value ; GrowthAchievable = 'true'} } diff --git a/internal/assertions/Instance.Assertions.ps1 b/internal/assertions/Instance.Assertions.ps1 index 9a996dc4..57045ee5 100644 --- a/internal/assertions/Instance.Assertions.ps1 +++ b/internal/assertions/Instance.Assertions.ps1 @@ -91,6 +91,12 @@ function Assert-TempDBSize { @((Get-DbaDbFile -SqlInstance $Instance -Database tempdb).Where{$_.Type -eq 0}.Size.Megabyte |Select-Object -Unique).Count | Should -Be 1 -Because "We want all the tempdb data files to be the same size - See https://blogs.sentryone.com/aaronbertrand/sql-server-2016-tempdb-fixes/ and https://www.brentozar.com/blitz/tempdb-data-files/ for more information" } +function Assert-DBGrowthEvent { + Param($Instance) + + (Get-DatabaseDiskFreeSpace -SqlInstance $Instance).Where{$_.GrowthAchievable -eq 'true'} | Should -Be 'true' -Because "We want enough space to let all the databases grow at least once more." +} + function Assert-InstanceSupportedBuild { Param( [string]$Instance,