Skip to content

Commit 10b6070

Browse files
Add FileNameFriendly property to DbaInstanceParameter for safe filenames
Fixes #30 When connecting via named pipes (e.g., .\SQLSERVER), the FullSmoName property returns values like "NP:.$SQLSERVER" which contain colons - invalid characters for Windows filenames. This causes Backup-DbaDbMasterKey to create truncated filenames like "NP" instead of the intended name. This commit adds a new FileNameFriendly property that sanitizes the instance name for use in filenames by replacing invalid characters (colons, backslashes, commas) with underscores. Changes: - Added FileNameFriendly property to DbaInstanceParameter class - Updated existing tests to verify FileNameFriendly output - Added comprehensive TestFileNameFriendly test covering various scenarios The main dbatools repository can now use FileNameFriendly instead of FullSmoName when generating backup filenames. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Chrissy LeMaire <potatoqualitee@users.noreply.github.com>
1 parent be6429e commit 10b6070

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

project/dbatools.Tests/Parameter/DbaInstanceParamaterTest.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ public void TestDotHostname()
9494
Assert.AreEqual(".", dbaInstanceParamater.FullName);
9595
Assert.IsTrue(dbaInstanceParamater.IsLocalHost);
9696
Assert.AreEqual("NP:.", dbaInstanceParamater.FullSmoName);
97+
Assert.AreEqual("NP_.", dbaInstanceParamater.FileNameFriendly);
9798
Assert.AreEqual(@"MSSQLSERVER", dbaInstanceParamater.InstanceName);
9899
Assert.AreEqual(@"[MSSQLSERVER]", dbaInstanceParamater.SqlInstanceName);
99100
Assert.AreEqual(@"[.]", dbaInstanceParamater.SqlFullName);
@@ -115,6 +116,7 @@ public void TestDotHostnameWithInstance()
115116
Assert.AreEqual(@".\instancename", dbaInstanceParamater.FullName);
116117
Assert.IsTrue(dbaInstanceParamater.IsLocalHost);
117118
Assert.AreEqual(@"NP:.\instancename", dbaInstanceParamater.FullSmoName);
119+
Assert.AreEqual(@"NP_._instancename", dbaInstanceParamater.FileNameFriendly);
118120
Assert.AreEqual(@"instancename", dbaInstanceParamater.InstanceName);
119121
Assert.AreEqual(@"[instancename]", dbaInstanceParamater.SqlInstanceName);
120122
Assert.AreEqual(@"[.\instancename]", dbaInstanceParamater.SqlFullName);
@@ -238,5 +240,39 @@ public void TestServerNameWithDash()
238240
Assert.AreEqual("[My-Instance.domain.local\\MyTestInstance]", dbaInstanceParamater.SqlFullName);
239241
Assert.IsFalse(dbaInstanceParamater.IsConnectionString);
240242
}
243+
244+
/// <summary>
245+
/// Tests that FileNameFriendly returns valid filenames for various connection types
246+
/// </summary>
247+
[TestMethod]
248+
public void TestFileNameFriendly()
249+
{
250+
// Test with named pipes using dot notation
251+
var npDot = new DbaInstanceParameter(".");
252+
Assert.AreEqual("NP_.", npDot.FileNameFriendly);
253+
Assert.IsFalse(npDot.FileNameFriendly.Contains(":"));
254+
255+
// Test with named pipes using dot notation with instance
256+
var npDotInstance = new DbaInstanceParameter(@".\SQLSERVER");
257+
Assert.AreEqual("NP_._SQLSERVER", npDotInstance.FileNameFriendly);
258+
Assert.IsFalse(npDotInstance.FileNameFriendly.Contains(":"));
259+
Assert.IsFalse(npDotInstance.FileNameFriendly.Contains("\\"));
260+
261+
// Test with TCP protocol
262+
var tcpInstance = new DbaInstanceParameter("TCP:server\\instance");
263+
Assert.AreEqual("TCP_server_instance", tcpInstance.FileNameFriendly);
264+
Assert.IsFalse(tcpInstance.FileNameFriendly.Contains(":"));
265+
Assert.IsFalse(tcpInstance.FileNameFriendly.Contains("\\"));
266+
267+
// Test with port number
268+
var withPort = new DbaInstanceParameter("server,1433");
269+
Assert.AreEqual("server_1433", withPort.FileNameFriendly);
270+
Assert.IsFalse(withPort.FileNameFriendly.Contains(","));
271+
272+
// Test with regular instance name (no protocol)
273+
var regular = new DbaInstanceParameter("server\\instance");
274+
Assert.AreEqual("server_instance", regular.FileNameFriendly);
275+
Assert.IsFalse(regular.FileNameFriendly.Contains("\\"));
276+
}
241277
}
242278
}

project/dbatools/Parameter/DbaInstanceParameter.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,24 @@ public string FullSmoName
118118
}
119119
}
120120

121+
/// <summary>
122+
/// Full name of the instance sanitized for use in file names, replacing invalid characters
123+
/// </summary>
124+
[ParameterContract(ParameterContractType.Field, ParameterContractBehavior.Mandatory)]
125+
public string FileNameFriendly
126+
{
127+
get
128+
{
129+
string temp = _ComputerName;
130+
if (_NetworkProtocol == SqlConnectionProtocol.NP) { temp = "NP_" + temp; }
131+
if (_NetworkProtocol == SqlConnectionProtocol.TCP) { temp = "TCP_" + temp; }
132+
if (!String.IsNullOrEmpty(_InstanceName) && _Port > 0) { return String.Format(@"{0}_{1}_{2}", temp, _InstanceName, _Port); }
133+
if (_Port > 0) { return temp + "_" + _Port; }
134+
if (!String.IsNullOrEmpty(_InstanceName)) { return temp + "_" + _InstanceName; }
135+
return temp;
136+
}
137+
}
138+
121139
/// <summary>
122140
/// Name of the computer as used in an SQL Statement
123141
/// </summary>

0 commit comments

Comments
 (0)