Skip to content

Commit

Permalink
DbatoolsPath (#6181)
Browse files Browse the repository at this point in the history
* Implementing paths

* ran against Invoke-DbatoolsFormatter

* put that back, then add after

* add commands

* fix up params, add test

* named it properly
  • Loading branch information
FriedrichWeinmann authored and potatoqualitee committed Nov 29, 2019
1 parent 9a2de55 commit 1f4f89f
Show file tree
Hide file tree
Showing 13 changed files with 199 additions and 7 deletions.
3 changes: 3 additions & 0 deletions dbatools.psd1
Expand Up @@ -653,6 +653,9 @@
'Get-DbatoolsConfig',
'Get-DbatoolsConfigValue',
'Register-DbatoolsConfig',
# Managed Path Commands
'Get-DbatoolsPath',
'Set-DbatoolsPath',
# Unknown
'Get-DbaErrorLog',
'Get-DbaManagementObject',
Expand Down
4 changes: 3 additions & 1 deletion dbatools.psm1
Expand Up @@ -763,7 +763,9 @@ $script:xplat = @(
'Install-DbaFirstResponderKit',
'Install-DbaWhoIsActive',
'Update-Dbatools',
'Add-DbaServerRoleMember'
'Add-DbaServerRoleMember',
'Get-DbatoolsPath',
'Set-DbatoolsPath'
)

$script:noncoresmo = @(
Expand Down
2 changes: 1 addition & 1 deletion functions/Get-DbaRegServer.ps1
Expand Up @@ -119,7 +119,7 @@ function Get-DbaRegServer {
}
process {
if (-not $PSBoundParameters.SqlInstance -and -not ($IsLinux -or $IsMacOs)) {
$null = Get-ChildItem -Recurse "$env:APPDATA\Microsoft\*sql*" -Filter RegSrvr.xml | Sort-Object LastWriteTime -Descending | Select-Object -First 1
$null = Get-ChildItem -Recurse "$(Get-DbatoolsPath -Name appdata)\Microsoft\*sql*" -Filter RegSrvr.xml | Sort-Object LastWriteTime -Descending | Select-Object -First 1
}

$servers = @()
Expand Down
31 changes: 31 additions & 0 deletions functions/Get-DbatoolsPath.ps1
@@ -0,0 +1,31 @@
function Get-DbatoolsPath {
<#
.SYNOPSIS
Access a configured path.
.DESCRIPTION
Access a configured path.
Paths can be configured using Set-DbatoolsPath or using the configuration system.
To register a path using the configuration system create a setting key named like this:
"Path.Managed.<PathName>"
For example the following setting points at the temp path:
"Path.Managed.Temp"
.PARAMETER Name
Name of the path to retrieve.
.EXAMPLE
PS C:\> Get-DbatoolsPath -Name 'temp'
Returns the temp path.
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true, Position = 0)]
[string]$Name
)

process {
Get-DbatoolsConfigValue -FullName "Path.Managed.$Name"
}
}
4 changes: 2 additions & 2 deletions functions/Invoke-DbaQuery.ps1
Expand Up @@ -190,7 +190,7 @@ function Invoke-DbaQuery {

switch -regex ($uri.Scheme) {
"http" {
$tempfile = "$env:TEMP\$temporaryFilesPrefix-$temporaryFilesCount.sql"
$tempfile = "$(Get-DbatoolsPath -Name temp)\$temporaryFilesPrefix-$temporaryFilesCount.sql"
try {
try {
Invoke-TlsWebRequest -Uri $item -OutFile $tempfile -ErrorAction Stop
Expand Down Expand Up @@ -255,7 +255,7 @@ function Invoke-DbaQuery {
}

try {
$newfile = "$env:TEMP\$temporaryFilesPrefix-$temporaryFilesCount.sql"
$newfile = "$(Get-DbatoolsPath -Name temp)\$temporaryFilesPrefix-$temporaryFilesCount.sql"
Set-Content -Value $code -Path $newfile -Force -ErrorAction Stop -Encoding UTF8
$files += $newfile
$temporaryFilesCount++
Expand Down
48 changes: 48 additions & 0 deletions functions/Set-DbatoolsPath.ps1
@@ -0,0 +1,48 @@
function Set-DbatoolsPath {
<#
.SYNOPSIS
Configures or updates a path under a name.
.DESCRIPTION
Configures or updates a path under a name.
The path can be persisted using the "-Register" command.
Paths setup like this can be retrieved using Get-DbatoolsPath.
.PARAMETER Name
Name the path should be stored under.
.PARAMETER Path
The path that should be returned under the name.
.PARAMETER Register
Registering a path in order for it to persist across sessions.
.PARAMETER Scope
The configuration scope it should be registered under.
Defaults to UserDefault.
Configuration scopes are the default locations configurations are being stored at.
.EXAMPLE
PS C:\> Set-DbatoolsPath -Name 'temp' -Path 'C:\temp'
Configures C:\temp as the current temp path. (does not override $env:temp !)
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
[CmdletBinding(DefaultParameterSetName = 'Default')]
param (
[Parameter(Mandatory = $true)]
[string]$Name,
[Parameter(Mandatory = $true)]
[string]$Path,
[Parameter(ParameterSetName = 'Register', Mandatory = $true)]
[switch]$Register,
[Parameter(ParameterSetName = 'Register')]
[Sqlcollaborative.Dbatools.Configuration.ConfigScope]
$Scope = [Sqlcollaborative.Dbatools.Configuration.ConfigScope]::UserDefault
)

process {
Set-DbatoolsConfig -FullName "Path.Managed.$Name" -Value $Path
if ($Register) { Register-DbatoolsConfig -FullName "Path.Managed.$Name" -Scope $Scope }
}
}
2 changes: 1 addition & 1 deletion functions/Uninstall-DbatoolsWatchUpdate.ps1
Expand Up @@ -39,7 +39,7 @@ function Uninstall-DbatoolsWatchUpdate {
Write-Message -Level Warning -Message "Task doesn't exist. Skipping removal."
} else {
Write-Message -Level Output -Message "Removing watchupdate.xml."
$file = "$env:LOCALAPPDATA\dbatools\watchupdate.xml"
$file = "$(Get-DbatoolsPath -Name localappdata)\dbatools\watchupdate.xml"
Remove-Item $file -ErrorAction SilentlyContinue

Write-Message -Level Output -Message "Removing Scheduled Task 'dbatools version check'."
Expand Down
2 changes: 1 addition & 1 deletion functions/Watch-DbatoolsUpdate.ps1
Expand Up @@ -49,7 +49,7 @@ function Watch-DbatoolsUpdate {

if ($galleryVersion -le $localVersion) { return }

$file = "$env:LOCALAPPDATA\dbatools\watchupdate.xml"
$file = "$(Get-DbatoolsPath -Name localappdata)\dbatools\watchupdate.xml"

$new = [PSCustomObject]@{
NotifyVersion = $galleryVersion
Expand Down
58 changes: 57 additions & 1 deletion internal/configurations/settings/paths.ps1
Expand Up @@ -2,6 +2,7 @@
This is designed for all paths you need configurations for.
#>

#region Weird Path Calculation Thingy
$temp = ([System.IO.Path]::GetTempPath()).TrimEnd("\")
$docs = $([Environment]::GetFolderPath("MyDocuments"))

Expand Down Expand Up @@ -42,6 +43,7 @@ if (-not $script:AppData) {
if (-not (Test-Path -Path $script:AppData)) {
$null = New-Item -Path $script:AppData -ItemType Directory -Force
}
#endregion Weird Path Calculation Thingy

# The default path where dbatools stores persistent data
Set-DbatoolsConfig -FullName 'Path.DbatoolsData' -Value (Join-DbaPath $script:AppData "PowerShell" "dbatools") -Initialize -Validation string -Handler { } -Description "The path where dbatools stores persistent data on a per user basis."
Expand All @@ -59,4 +61,58 @@ Set-DbatoolsConfig -FullName 'Path.TagCache' -Value (Resolve-Path "$script:PSMod
Set-DbatoolsConfig -FullName 'Path.Servers' -Value (Join-DbaPath $script:AppData "PowerShell" "dbatools" "servers.xml") -Initialize -Validation string -Handler { } -Description "The file in which dbatools stores the current user's server list, as managed by Get/Add/Update-DbaInstanceList"

# The default path for writing exported SQL scripts
Set-DbatoolsConfig -FullName 'Path.DbatoolsExport' -Value (Join-DbaPath -Path $docs -Child "DbatoolsExport") -Initialize -Validation string -Handler { [Sqlcollaborative.Dbatools.Message.LogHost]::LoggingPath = $args[0] } -Description "The default path where dbatools writes scripts generated by Export-* functions."
Set-DbatoolsConfig -FullName 'Path.DbatoolsExport' -Value (Join-DbaPath -Path $docs -Child "DbatoolsExport") -Initialize -Validation string -Handler { [Sqlcollaborative.Dbatools.Message.LogHost]::LoggingPath = $args[0] } -Description "The default path where dbatools writes scripts generated by Export-* functions."

#region Managed Path Stuff
#region $Path_Temp
$path_Temp = $env:TEMP
if (-not $path_Temp) { $path_Temp = ([System.IO.Path]::GetTempPath()).TrimEnd("\/") }
if (-not $path_Temp) { $path_Temp = ([System.IO.Path]::GetTempPath()).TrimEnd("\/") }
if (-not $path_Temp) {
if ($IsLinux -or $IsMacOs) { $path_Temp = '/tmp' }
else { $path_Temp = 'C:\windows\temp' }
}
#endregion $Path_Temp

#region $path_localAppData
if ($IsLinux -or $IsMacOs) {
# Defaults to $Env:XDG_CONFIG_HOME on Linux or MacOS ($HOME/.config/)
$path_LocalAppData = $Env:XDG_CONFIG_HOME
if (-not $path_LocalAppData) { $path_LocalAppData = Join-Path $HOME .config/ }
} else {
# Defaults to $Env:LocalAppData on Windows
$path_LocalAppData = $Env:LocalAppData
if (-not $path_LocalAppData) { $path_LocalAppData = [Environment]::GetFolderPath("LocalApplicationData") }
}
#endregion $path_localAppData

#region $path_AppData
if ($IsLinux -or $IsMacOs) {
# Defaults to the first value in $Env:XDG_CONFIG_DIRS on Linux or MacOS (or $HOME/.local/share/)
$path_AppData = @($Env:XDG_CONFIG_DIRS -split ([IO.Path]::PathSeparator))[0]
if (-not $path_AppData) { $path_AppData = Join-Path $HOME .local/share/ }
} else {
# Defaults to $Env:AppData on Windows
$path_AppData = $env:APPDATA
if (-not $path_AppData) { $path_AppData = [Environment]::GetFolderPath("ApplicationData") }
}
#endregion $path_AppData

#region $path_ProgramData
if ($IsLinux -or $IsMacOs) {
# Defaults to /etc/xdg elsewhere
$XdgConfigDirs = $Env:XDG_CONFIG_DIRS -split ([IO.Path]::PathSeparator) | Where-Object { $_ -and (Test-Path $_) }
if ($XdgConfigDirs.Count -gt 1) { $path_ProgramData = $XdgConfigDirs[1] }
else { $path_ProgramData = "/etc/xdg/" }
} else {
# Defaults to $Env:ProgramData on Windows
$path_ProgramData = $env:ProgramData
if (-not $path_ProgramData) { $path_ProgramData = [Environment]::GetFolderPath("CommonApplicationData") }
}
#endregion $path_ProgramData

Set-DbatoolsConfig -FullName 'Path.Managed.Temp' -Value $path_Temp -Initialize -Validation 'string' -Description "Path pointing at the temp path. Used with Get-DbatoolsPath."
Set-DbatoolsConfig -FullName 'Path.Managed.LocalAppData' -Value $path_LocalAppData -Initialize -Validation 'string' -Description "Path pointing at the LocalAppData path. Used with Get-DbatoolsPath."
Set-DbatoolsConfig -FullName 'Path.Managed.AppData' -Value $path_AppData -Initialize -Validation 'string' -Description "Path pointing at the AppData path. Used with Get-DbatoolsPath."
Set-DbatoolsConfig -FullName 'Path.Managed.ProgramData' -Value $path_ProgramData -Initialize -Validation 'string' -Description "Path pointing at the ProgramData path. Used with Get-DbatoolsPath."
#endregion Managed Path Stuff
23 changes: 23 additions & 0 deletions internal/dynamicparams/path.ps1
@@ -0,0 +1,23 @@
#region Tepp Data return: Path
$ScriptBlock = {
param (
$commandName,

$parameterName,

$wordToComplete,

$commandAst,

$fakeBoundParameter
)


foreach ($name in (([Sqlcollaborative.Dbatools.Configuration.ConfigurationHost]::Configurations.Values | Where-Object FullName -like "path.managed.*").FullName -replace '^path\.managed\.')) {
if ($name -notlike "$wordToComplete*") { continue }
New-DbaTeppCompletionResult -CompletionText $name -ToolTip $name
}
}

Register-DbaTeppScriptblock -ScriptBlock $ScriptBlock -Name path
#endregion Tepp Data return: Path
1 change: 1 addition & 0 deletions internal/scripts/insertTepp.ps1
Expand Up @@ -74,6 +74,7 @@ Register-DbaTeppArgumentCompleter -Command "Find-DbaCommand" -Parameter Tag -Nam
Register-DbaTeppArgumentCompleter -Command "Get-DbatoolsConfig", "Get-DbatoolsConfigValue", "Register-DbatoolsConfig", "Set-DbatoolsConfig" -Parameter FullName -Name config
Register-DbaTeppArgumentCompleter -Command "Get-DbatoolsConfig", "Register-DbatoolsConfig", "Set-DbatoolsConfig" -Parameter Module -Name configmodule
Register-DbaTeppArgumentCompleter -Command "Get-DbatoolsConfig", "Register-DbatoolsConfig", "Set-DbatoolsConfig" -Parameter Name -Name config_name
Register-DbaTeppArgumentCompleter -Command "Get-DbatoolsPath", "Set-DbatoolsPath" -Parameter Name -Name path
Register-DbaTeppArgumentCompleter -Command "Get-DbaProcess", "Stop-DbaProcess" -Parameter ExcludeSpid -Name processSpid
Register-DbaTeppArgumentCompleter -Command "Get-DbaProcess", "Stop-DbaProcess" -Parameter Hostname -Name processHostname
Register-DbaTeppArgumentCompleter -Command "Get-DbaProcess", "Stop-DbaProcess" -Parameter Program -Name processProgram
Expand Down
14 changes: 14 additions & 0 deletions tests/Get-DbatoolsPath.Tests.ps1
@@ -0,0 +1,14 @@
$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 = 'Name'
$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 changes: 14 additions & 0 deletions tests/Set-DbatoolsPath.Tests.ps1
@@ -0,0 +1,14 @@
$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 = 'Name', 'Path', 'Register', 'Scope'
$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
}
}
}

0 comments on commit 1f4f89f

Please sign in to comment.