From 19f83350693a70febb423a43cf07a9ff84f90c92 Mon Sep 17 00:00:00 2001 From: Till Mitlehner Date: Mon, 31 Aug 2026 16:14:26 +0200 Subject: [PATCH 1/2] Fix apostrophes in user profile REST calls --- src/Commands/Principals/ExportUserInfo.cs | 2 +- src/Commands/Principals/RemoveUserInfo.cs | 5 +++-- src/Commands/UserProfiles/ExportUserProfile.cs | 2 +- src/Commands/UserProfiles/RemoveUserProfile.cs | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Commands/Principals/ExportUserInfo.cs b/src/Commands/Principals/ExportUserInfo.cs index 7f373b00f2..230a403581 100644 --- a/src/Commands/Principals/ExportUserInfo.cs +++ b/src/Commands/Principals/ExportUserInfo.cs @@ -32,7 +32,7 @@ protected override void ExecuteCmdlet() var site = Tenant.GetSiteByUrl(siteUrl); AdminContext.Load(site); AdminContext.ExecuteQueryRetry(); - var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}"); + var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}".Replace("'", "''")); var results = RestHelper.Get>(Connection.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/GetSPUserInformation(accountName=@a,siteId=@b)?@a='{normalizedUserName}'&@b='{site.Id}'", AdminContext, false); var record = new PSObject(); foreach (var item in results.Items) diff --git a/src/Commands/Principals/RemoveUserInfo.cs b/src/Commands/Principals/RemoveUserInfo.cs index bd454564c1..9d4e99cccf 100644 --- a/src/Commands/Principals/RemoveUserInfo.cs +++ b/src/Commands/Principals/RemoveUserInfo.cs @@ -35,7 +35,7 @@ protected override void ExecuteCmdlet() var site = Tenant.GetSiteByUrl(siteUrl); AdminContext.Load(site); AdminContext.ExecuteQueryRetry(); - var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}"); + var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}".Replace("'", "''")); RestResultCollection results = null; if (!ParameterSpecified(nameof(RedactName))) { @@ -43,7 +43,8 @@ protected override void ExecuteCmdlet() } else { - results = RestHelper.Post>(HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/RemoveSPUserInformation(accountName=@a,siteId=@b,redactName=@c)?@a='{normalizedUserName}'&@b='{site.Id}'&@c='{RedactName}'", this.AccessToken, false); + var redactName = UrlUtilities.UrlEncode(RedactName.Replace("'", "''")); + results = RestHelper.Post>(HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/RemoveSPUserInformation(accountName=@a,siteId=@b,redactName=@c)?@a='{normalizedUserName}'&@b='{site.Id}'&@c='{redactName}'", this.AccessToken, false); } var record = new PSObject(); foreach (var item in results.Items) diff --git a/src/Commands/UserProfiles/ExportUserProfile.cs b/src/Commands/UserProfiles/ExportUserProfile.cs index 7223942f10..1db77a12c6 100644 --- a/src/Commands/UserProfiles/ExportUserProfile.cs +++ b/src/Commands/UserProfiles/ExportUserProfile.cs @@ -20,7 +20,7 @@ protected override void ExecuteCmdlet() { hostUrl = hostUrl.Substring(0, hostUrl.Length - 1); } - var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}"); + var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}".Replace("'", "''")); var results = RestHelper.Get>(Connection.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/GetUserProfileProperties(accountName=@a)?@a='{normalizedUserName}'", AdminContext, false); var record = new PSObject(); foreach (var item in results.Items) diff --git a/src/Commands/UserProfiles/RemoveUserProfile.cs b/src/Commands/UserProfiles/RemoveUserProfile.cs index 16bcbd960a..f095f5b8cf 100644 --- a/src/Commands/UserProfiles/RemoveUserProfile.cs +++ b/src/Commands/UserProfiles/RemoveUserProfile.cs @@ -22,7 +22,7 @@ protected override void ExecuteCmdlet() { hostUrl = hostUrl.Substring(0, hostUrl.Length - 1); } - var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}"); + var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}".Replace("'", "''")); if (!ParameterSpecified(nameof(UserId))) { From 9d8f6e92a9de04e413f60e3ae4888de9dadabd5d Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 3 Sep 2026 01:40:28 +0200 Subject: [PATCH 2/2] Adding changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e44512516..d594a5956c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Changed ### Fixed +- Using UPNs with an apostrophe in it not working with `Remove-PnPUserProfile`, `Export-PnPUserProfile`, `Export-PnPUserInfo`, and `Remove-PnPUserInfo`. The apostrophe is now escaped in the API request. [#5459](https://github.com/pnp/powershell/pull/5459) ## [3.4.1] @@ -24,6 +25,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Contributors - Gautam Sheth [gautamdsheth] +- [till-llit] ## [3.4.0]