@@ -20,9 +20,6 @@ function Export-DbaCredential {
2020
2121 For MFA support, please use Connect-DbaInstance.
2222
23- . PARAMETER Credential
24- Login to the target OS using alternative credentials. Accepts credential objects (Get-Credential)
25-
2623 . PARAMETER Path
2724 Specifies the directory where the exported T-SQL script file will be saved. Defaults to the configured DbatoolsExport path.
2825 Use this when you want to control where credential scripts are stored for organization or compliance requirements.
@@ -35,10 +32,6 @@ function Export-DbaCredential {
3532 Specifies which credential names to export by filtering on the Identity property. Accepts an array of credential names.
3633 Use this to export specific credentials instead of all credentials, particularly useful when migrating only certain application or service accounts.
3734
38- . PARAMETER InputObject
39- Accepts credential objects piped from Get-DbaCredential, allowing for advanced filtering and processing scenarios.
40- Use this in pipeline operations when you need to filter or process credentials before exporting them.
41-
4235 . PARAMETER ExcludePassword
4336 Exports credential definitions without the actual password values, replacing them with placeholder text.
4437 Use this for documentation purposes or when you need credential structure without sensitive data for security reviews.
@@ -47,6 +40,10 @@ function Export-DbaCredential {
4740 Adds the exported credential scripts to an existing file instead of overwriting it.
4841 Use this when consolidating credentials from multiple instances into a single deployment script.
4942
43+ . PARAMETER Passthru
44+ Returns the generated T-SQL script to the PowerShell pipeline instead of saving to file.
45+ Use this to capture the script in a variable, pipe to other commands, or display directly in the console.
46+
5047 . PARAMETER EnableException
5148 By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message.
5249 This avoids overwhelming you with "sea of red" exceptions, but is inconvenient because it basically disables advanced scripting.
@@ -84,23 +81,18 @@ function Export-DbaCredential {
8481 [CmdletBinding ()]
8582 param (
8683 [DbaInstanceParameter []]$SqlInstance ,
87- [string []]$Identity ,
8884 [PSCredential ]$SqlCredential ,
89- [PSCredential ]$Credential ,
9085 [string ]$Path = (Get-DbatoolsConfigValue - FullName ' Path.DbatoolsExport' ),
9186 [Alias (" OutFile" , " FileName" )]
9287 [string ]$FilePath ,
88+ [string []]$Identity ,
9389 [switch ]$ExcludePassword ,
9490 [switch ]$Append ,
95- [Parameter (ValueFromPipeline )]
96- [Microsoft.SqlServer.Management.Smo.Credential []]$InputObject ,
91+ [switch ]$Passthru ,
9792 [switch ]$EnableException
9893 )
9994 begin {
10095 $null = Test-ExportDirectory - Path $Path
101- $serverArray = @ ()
102- $credentialArray = @ { }
103- $credentialCollection = New-Object System.Collections.ArrayList
10496 }
10597 process {
10698 if (Test-FunctionInterrupt ) { return }
@@ -110,137 +102,78 @@ function Export-DbaCredential {
110102 return
111103 }
112104
113- if (-not $InputObject -and -not $SqlInstance ) {
114- Stop-Function - Message " You must pipe in a Credential or specify a SqlInstance"
115- return
116- }
117-
118- if (Test-Bound - ParameterName SqlInstance) {
119- foreach ($instance in $SqlInstance ) {
120- try {
121- try {
122- $server = Connect-DbaInstance - SqlInstance $instance - SqlCredential $SqlCredential - MinimumVersion 9
123- } catch {
124- Stop-Function - Message " Failure" - Category ConnectionError - ErrorRecord $_ - Target $instance - Continue
125- }
126-
127- $serverCreds = $server.Credentials
128- if (Test-Bound - ParameterName Identity) {
129- $serverCreds = $serverCreds | Where-Object Identity -In $Identity
130- }
131-
132- $InputObject += $serverCreds
133- } catch {
134- Stop-Function - Message " Error occurred while establishing connection to $instance " - Category ConnectionError - ErrorRecord $_ - Target $instance - Continue
105+ foreach ($instance in $SqlInstance ) {
106+ try {
107+ if ($ExcludePassword ) {
108+ Write-Message - Level Verbose - Message " Opening normal connection because we don't need the passwords."
109+ $server = Connect-DbaInstance - SqlInstance $instance - SqlCredential $SqlCredential - MinimumVersion 9
110+ } else {
111+ Write-Message - Level Verbose - Message " Opening dedicated admin connection for password retrieval."
112+ $server = Connect-DbaInstance - SqlInstance $instance - SqlCredential $SqlCredential - MinimumVersion 9 - DedicatedAdminConnection - WarningAction SilentlyContinue
135113 }
114+ } catch {
115+ Stop-Function - Message " Failure" - Category ConnectionError - ErrorRecord $_ - Target $instance - Continue
136116 }
137- }
138-
139- foreach ($input in $InputObject ) {
140- $server = $input.Parent
141- $instance = $server.DomainInstanceName
142117
143- if ($serverArray -notcontains $instance ) {
144- try {
145- if ($ExcludePassword ) {
146- $serverCreds = $server.Credentials
147- $creds = New-Object System.Collections.ArrayList
148-
149- foreach ($cred in $server.Credentials ) {
150- $credObject = [PSCustomObject ]@ {
151- Name = $cred.Name
152- Quotename = $server.Query (" SELECT QUOTENAME('$ ( $cred.Name.Replace (" '" , " ''" )) ') AS Quotename" ).Quotename
153- Identity = $cred.Identity.ToString ()
154- Password = ' '
155- MappedClassType = $cred.MappedClassType
156- ProviderName = $cred.ProviderName
157- }
158- $creds.Add ($credObject ) | Out-Null
159- }
160- $creds | Add-Member - MemberType NoteProperty - Name ' SqlInstance' - Value $instance
161- $creds | Add-Member - MemberType NoteProperty - Name ' ExcludePassword' - Value $ExcludePassword
162- $credentialCollection.Add ($credObject ) | Out-Null
163- } else {
164- if (-not (Test-SqlSa - SqlInstance $server )) {
165- Stop-Function - Message " Not a sysadmin on $instance . Quitting." - Target $instance - Continue
166- }
167-
168- Write-Message - Level Verbose - Message " Getting FullComputerName name for $instance ."
169- $fullComputerName = Resolve-DbaComputerName - ComputerName $server - Credential $Credential
170-
171- Write-Message - Level Verbose - Message " Checking if Remote Registry is enabled on $instance ."
172- try {
173- Invoke-Command2 - Raw - Credential $Credential - ComputerName $fullComputerName - ScriptBlock { Get-ItemProperty - Path " HKLM:\SOFTWARE\" } - ErrorAction Stop
174- } catch {
175- Stop-Function - Message " Can't connect to registry on $instance ." - Target $fullComputerName - ErrorRecord $_
176- return
177- }
178-
179- $creds = Get-DecryptedObject - SqlInstance $server - Type Credential
180- Write-Message - Level Verbose - Message " Adding Members"
181- $creds | Add-Member - MemberType NoteProperty - Name ' SqlInstance' - Value $instance
182- $creds | Add-Member - MemberType NoteProperty - Name ' ExcludePassword' - Value $ExcludePassword
183- $credentialCollection.Add ($creds ) | Out-Null
118+ if ($ExcludePassword ) {
119+ $credentials = foreach ($cred in $server.Credentials ) {
120+ [PSCustomObject ]@ {
121+ Name = $cred.Name
122+ Quotename = $server.Query (" SELECT QUOTENAME('$ ( $cred.Name.Replace (" '" , " ''" )) ') AS Quotename" ).Quotename
123+ Identity = $cred.Identity.ToString ()
124+ Password = ' <EnterStrongPasswordHere>'
125+ MappedClassType = $cred.MappedClassType
126+ ProviderName = $cred.ProviderName
184127 }
185- } catch {
186- Stop-Function - Continue - Message " Failure" - ErrorRecord $_
187128 }
188-
189- $serverArray += $instance
190-
191- $key = $instance + ' ::' + $input.Name
192- $credentialArray.add ( $key , $true )
193129 } else {
194- $key = $instance + ' ::' + $input.Name
195- $credentialArray.add ( $key , $true )
130+ $credentials = Get-DecryptedObject - SqlInstance $server - Type Credential
196131 }
197- }
198- }
199-
200- end {
201- $sql = @ ()
202- foreach ($cred in $credentialCollection ) {
203- Write-Message - Level Verbose - Message " Credentials in object = $ ( $cred.Count ) "
204132
205- foreach ($currentCred in $creds ) {
206- $FilePath = Get-ExportFilePath - Path $PSBoundParameters.Path - FilePath $PSBoundParameters.FilePath - ServerName $currentCred.SqlInstance - Type Sql
133+ if ($Identity ) {
134+ $credentials = $credentials | Where-Object Identity -in $Identity
135+ }
207136
208- $key = $currentCred .SqlInstance + ' :: ' + $currentCred .Name
209- if ( $credentialArray .ContainsKey ( $key ) ) {
210- $quotename = $currentCred .Quotename
211- $identity = $currentCred .Identity.Replace ( " ' " , " '' " )
137+ if ( -not $credentials ) {
138+ Write-Message - Level Verbose - Message " Nothing to export "
139+ continue
140+ }
212141
213- if ($currentCred.MappedClassType -like ' Cryptographic*' ) {
214- $providerName = $currentCred.ProviderName
215- $cryptoSql = " FOR CRYPTOGRAPHIC PROVIDER $providerName "
216- } else {
217- $cryptoSql = " "
218- }
142+ $FilePath = Get-ExportFilePath - Path $PSBoundParameters.Path - FilePath $PSBoundParameters.FilePath - Type sql - ServerName $instance
219143
220- if ($currentCred.ExcludePassword ) {
221- $sql += " CREATE CREDENTIAL $quotename WITH IDENTITY = N'$identity ', SECRET = N'<EnterStrongPasswordHere>'" + $cryptoSql
222- } else {
223- $password = $currentCred.Password.Replace (" '" , " ''" )
224- $sql += " CREATE CREDENTIAL $quotename WITH IDENTITY = N'$identity ', SECRET = N'$password '" + $cryptoSql
144+ $sql = @ ()
225145
146+ foreach ($cred in $credentials ) {
147+ $quotename = $cred.Quotename
148+ $identity = $cred.Identity.Replace (" '" , " ''" )
149+ $password = $cred.Password.Replace (" '" , " ''" )
150+ $cryptoSql = " "
151+ if ($cred.MappedClassType -like ' Cryptographic*' ) {
152+ $providerName = $cred.ProviderName
153+ $cryptoSql = " FOR CRYPTOGRAPHIC PROVIDER $providerName "
154+ }
155+ $sql += " CREATE CREDENTIAL $quotename WITH IDENTITY = N'$identity ', SECRET = N'$password '" + $cryptoSql
156+ }
226157
158+ if ($Passthru ) {
159+ $sql
160+ } else {
161+ try {
162+ if ($Append ) {
163+ Add-Content - Path $FilePath - Value $sql
164+ } else {
165+ Set-Content - Path $FilePath - Value $sql
227166 }
228-
229- Write-Message - Level Verbose - Message " Created Script for $quotename "
167+ Get-ChildItem - Path $FilePath
168+ } catch {
169+ Stop-Function - Message " Can't write to $FilePath " - ErrorRecord $_ - Continue
230170 }
231171 }
232172
233- try {
234- if ($Append ) {
235- Add-Content - Path $FilePath - Value $sql
236- } else {
237- Set-Content - Path $FilePath - Value $sql
238- }
239- } catch {
240- Stop-Function - Message " Can't write to $FilePath " - ErrorRecord $_ - Continue
173+ # Disconnect DAC connection if it was opened
174+ if (-not $ExcludePassword ) {
175+ $null = $server | Disconnect-DbaInstance - WhatIf:$false
241176 }
242- Get-ChildItem - Path $FilePath
243- Write-Message - Level Verbose - Message " Credentials exported to $FilePath "
244177 }
245178 }
246179}
0 commit comments