Cannot export site template - powershell

I'm trying to get site template and getting error:
PS C:\Windows\system32> Get-PnPSiteTemplate -Out template.xml
Get-PnPSiteTemplate : GetAccessTokenAsync() called without an ACS token generator. Specify in AuthenticationManager constructor the authentication parameters
At line:1 char:1
Get-PnPSiteTemplate -Out template.xml
CategoryInfo : WriteError: (:) [Get-PnPSiteTemplate], ArgumentException
FullyQualifiedErrorId : EXCEPTION,PnP.PowerShell.Commands.Provisioning.Site.GetSiteTemplate
Version:
pnp.powershell 1.6.0

I had the same issue and after quite some time invested in troubleshooting, I've figured out that the export gets interrupted once it iterates over a list. It is not related to the site you're trying to export because it happened also on other, newly created sites.
It turned out that the problem was that the PNP Module requires Admin Consent since it can manipulate almost all components of O365.
Solution: Connect to the site with the following command:
Connect-PnPOnline -interactive -URL "Your Site Url"
Provide admin consent to PnP and then try to export the site template with:
Get-PnPSiteTemplate -Out "File Location" # Use handlers and other params if needed
If the prompt window doesn't show up, run the following command first:
register-pnpmanagementshellaccess # See notes before running this cmdlet
Note: Admin consent requires additional permissions and SharePoint Admin role is not enough! So either ask a Global Admin to consent for you or ask for additional AD permissions. If I'm not mistaken Application Administrator role should be the right choice.

This seems to have worked for me.
Get-PnPSiteTemplate -out template.xml -ExcludeHandlers Lists,ApplicationLifecycleManagement
It seems the lists and ALM sections need an ACS token generator and that fails with UseWebLogin.
This is what I got on version 1.7.10, but I have used 1.7.0 and 1.5.0 and seen the same issues. I don't know if the older versions have more problematic modules.
Method: I found this resolution by running Set-PnPTraceLog -on -logfile log.txt -Level Debug and Set-PnPTraceLog -off, then reviewing log file to see which module failed.
I may use the Export-PnPListToSiteTemplate and see how that goes in getting list XML for the template file.

I had the same issue with PnP.PowerShell 1.6.0. I was using Connect-PnPOnline command with -UseWebLogin flag because my account had multi factor authentication turned on.
My solution was to disable MFA for my user and connect without the "-UseWebLogin" flag. Then Get-PnPSiteTemplate command worked without any issues.
I'm not sure why this is happening, but I'll use this workaround for now :)

Related

PowerShell, SharePoint: Get-PnPSiteTemplate Error

i am getting an error using PnP PowerShell cmdlet: Get-PnPSiteTemplate. I am a global admin and site collection admin as well.
Custom Scripts are enabled:
set-sposite https://tenant.sharepoint.com/sites/TestSite -denyaddandcustomizepages $false
Connect-PnPOnline -Url https://tenant.sharepoint.com/sites/TestSite -Interactive
Get-PnPSiteTemplate -Out "C:TempDemo.xml"
Get-PnPSiteTemplate : Attempted to perform an unauthorized operation.
At C:\Users\userX\Desktop\Script.ps1:3 char:1
+ Get-PnPSiteTemplate -Out "C:TempDemo.xml"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (:) [Get-PnPSiteTemplate], ServerUnauthorizedAccessException
+ FullyQualifiedErrorId : EXCEPTION,PnP.PowerShell.Commands.Provisioning.Site.GetSiteTemplate
Anyone an idea? MS says PnP is open source, so no really support...
Goal is to copy a complete SharePoint list with all items and meta data to anothe site. Like this:
https://www.drware.com/copy-a-list-with-list-items-to-another-site/
Thanks! :)
I rechecked the command with latest version of PnP.PowerShell (version 1.7.0) on a clean communication site with a sample list with couple of items, nothing more, and works 🤔.
Could you also first retry on some test clean site with just one custom list and see if you have the same error? Maybe the problem you are having is connected to some customization you have on this site as the Get-PnPSiteTemplate without any parameters will export an template of the full site (including the list, but also all other stuff like some custom apps which maybe you don't have permission to do)
other thing you could try is to run the cmdlet to retrieve only the list you are interested in together with data:
# this will export the template only of the selected list
Get-PnPSiteTemplate -Out "C:\TempDemo.xml" -ListsToExtract "testList" -Handlers Lists -Force
# this will populate the list with data of the list
Add-PnPDataRowsToSiteTemplate -Path "C:\TempDemo.xml" -List "testList"

Automated way to purge SPO User Profiles

As part of a clean up task, I'm looking for a way to programmatically purge deleted AAD accounts from the User Profile Manager in Sharepoint Online.
I was using the Sharepoint Powershell module (Microsoft.Online.SharePoint.PowerShell) to manually do it, using the Remove-SPOUserProfile commandlet, which worked perfectly if I was using it in an interactive session. But as soon as I tried implementing my script into Azure Automation I found that particular module falls back to Basic Authentication when using a PSCredential object in the Connect-SPOService statement. And Basic Auth is blocked at my Organisation (I can't see them allowing it just for me!)
I found the PnP Module (PnP.PowerShell), which does allow authentication via stored credentials. But it doesn't have an equivalent User Profile Remove cmdlet.
Finally, I tried resorting to pure REST API, and while I can get an existing user profile, I can't get a profile for an account that has been deleted (marked as 'Profiles Missing from Import' in the SPO ProfMngr.aspx page). This is because the SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=#v) API needs to have an exact match (eg i:0#.f|membership|vardhaman#siteurl.onmicrosoft.com), and when an AAD account is deleted the profile username gets DELETED-<GUID> appended to it.
So my questions are:
Am I right or wrong about the sharepoint module and stored creds? (IE, so the module can be used from Azure Automation with a service principal or service account)
Am I right or wrong about the PnP module and it is missing the similar Remove-SPOUserProfile?
With the REST API, how do you search for profiles, especially profiles "missing from import"?
Is there some way to predict what the DELETED-<GUID> will be for a given user? Because I was able to get a user profile if I looked up the full deleted name and supply that to my REST call.
The official documentation on this is light - the old traditional sharepoint APIs aren't being developed any more, in favour of MS Graph, but the Graph Documentation doesn't seem to cover my particular use case.
Any pointers appreciated
Update 1
Thanks #Michael Han_MSFT.
I was using a pre-release/nightly build (0.3.32) but looking at Release documentation so didn't realise remove profile was in there.
I'm still getting problems though:
Connect-PnPOnline `
-url "https://<tenantname>.sharepoint.com" `
-ClientId $ClientId `
-ClientSecret $ClientSecret
# $guest1 = Guest account's email address
$azureEmail = ($guest1 -replace "#", "_") + "#ext##<tenantname>.onmicrosoft.com"
Remove-PnPUserProfile `
-LoginName $azureEmail
Remove-PnPUserProfile : The remote server returned an error: (401) Unauthorized.
At line:11 char:1
+ Remove-PnPUserProfile `
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Remove-PnPUserProfile], WebException
+ FullyQualifiedErrorId : System.Net.WebException,PnP.PowerShell.Commands.UserProfiles.RemoveUserProf
ile
So I tweaked the URL:
Connect-PnPOnline `
-url "https://<tenantname>-admin.sharepoint.com" `
-ClientId $ClientId `
-ClientSecret $ClientSecret
$azureEmail = ($guest1 -replace "#", "_") + "#ext##azurediagovt.onmicrosoft.com"
Remove-PnPUserProfile `
-LoginName $azureEmail
Remove-PnPUserProfile :
At line:11 char:1
+ Remove-PnPUserProfile `
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (:) [Remove-PnPUserProfile], HttpRequestException
+ FullyQualifiedErrorId : EXCEPTION,PnP.PowerShell.Commands.UserProfiles.RemoveUserProfile
So you can see if I go to <tenantname> I get a 401, but if I go to <tenantname>-name the response is simply blank.
I was certain I had given my App the right permissions (Is there some way to review what permissions have been assigned?)
In AppInv.aspx I think had this permissions code (I was following a couple of blogs):
<AppPermissionRequests AllowAppOnlyPolicy="true">
<AppPermissionRequest Scope="http://sharepoint/content/Tenant" Right="FullControl"/>
<AppPermissionRequest Scope="http://sharepoint/social/Tenant" Right="FullControl"/>
</AppPermissionRequests>
As a further test, I tried the PnP version of what I was doing in REST (Get-PnpUserProfileProperty) and got
Get-PnPUserProfileProperty : Current user is not a tenant administrator.
At line:1 char:1
+ Get-PnPUserProfileProperty -Connection $pnpctx -Account "scottdu#data ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (:) [Get-PnPUserProfileProperty], ServerException
+ FullyQualifiedErrorId : EXCEPTION,PnP.PowerShell.Commands.UserProfiles.GetUserProfileProperty
Which is strange, because REST would give me a results.d response.
At this stage, I could look at making the App Id a Sharepoint Service Admin (I already have approval to allow Azure Automation to have whatever rights it needs to solve this).
(Update 1a: Made no difference, unless there is a delay between assigning the role and the permissions taking affect).
AAD registered app can be used to connect PnpOnline and delete user profile. Please see my below steps:
(Main refer article: https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread)
Step1:Registering an Azure AD application in the Azure Active Directory tenant that is linked to your Office 365 tenant and grant permission
Use admin account to access https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps. Click “New registration” and create a name of your app.
Go to “API permissions” and click on the "Add a permission" button and grant SharePoint API permission.
Select needed permissions.
Admin need to consent for those permissions, after that in status column will show green.
Step2: Create a self signed certificate and connect with app
Go to this link(https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread#setting-up-an-azure-ad-app-for-app-only-access), copy the scripts and save as “Create-SelfSignedCertificate.ps1”.
Run below command with PowerShell. You will be asked to give a password to encrypt your private key, and both the .PFX file and .CER file will be exported to the current folder.
.\Create-SelfSignedCertificate.ps1 -CommonName "YourCompanyName"
-StartDate 2020-1-09 -EndDate 2022-10-01
Go to AAD app, click on "Certificates & secrets" in the left menu bar. Click on the "Upload certificate" button, select the .CER file you generated and upload it.
Step3: Connect pnp online and perform delete profile
$ Connect-PnPOnline -ClientId <$application client id as copied over
from the AAD app registration above> -CertificatePath '<$path to the
PFX file generated by the PowerShell script above>'
-CertificatePassword (ConvertTo-SecureString -AsPlainText "<$password assigned to the generated certificate pair above>" -Force) -Url
https://<$yourtenant>.sharepoint.com -Tenant
"<$tenantname>.onmicrosoft.com"
$Remove-PnPUserProfile -LoginName $UPN
For REST api way, I found this article noted REST for delete user profile is not implemented.
(https://learn.microsoft.com/en-us/sharepoint/dev/general-development/work-with-user-profiles-in-sharepoint)
You could try the command : Remove-PnPUserProfile
https://pnp.github.io/powershell/cmdlets/Remove-PnPUserProfile.html
You should install the prerelease version of PnP.PowerShell:
https://www.powershellgallery.com/packages/PnP.PowerShell/0.3.8-nightly
Update:
You could try to use tenant administrator account to connect the sharepoint admin site, then run the command Remove-PnPUserProfile. This works for me:

Powershell connecting to Sharepoint online using Active directory

To start, I am using Windows 7, I am a full adminstrator on this machine
I have tried other machines and ran as an administrator as well
I am only a sharepoint site collection admin
In powershell we connect to Sharepoint online. during this process, if I use Connect-PnPOnline -Url $masterSiteUrl -useweblogin, I get prompted for a username, however the next screen is blank and stays there.
when I do a view source of that page I get
d>Redirecting....myshn.net/certcheck" method="POST">
I do have scripting enabled and sometimes I get a certificate issue, I have clicked "Install Certificate" although I am not sure what it did, but it still doesnt work
Ive also tried -SPOManagementShell and -ClearTokenCache
and get the following error
Connect-PnPOnline : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:1
+ Connect-PnPOnline -Url $masterSiteUrl -useweblogin -spoManagementShel ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Connect-PnPOnline], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,SharePointPnP.PowerShell.Commands.Base.ConnectOnline
See this:
Connect to all Office 365 services in a single Windows PowerShell
and this...
Connect to all Office 365 Services PowerShell - Supports MFA too
Using our All-in-One PowerShell script, you can connect to all Office
365 Services using a single cmdlet. It supports both MFA and non-MFA
account -Exchange Online -Azure AD -SharePoint Online -Skype for
Business Online -Security & Compliance Center -Teams
Download: ConnectO365Services.ps1
O365_Logon 1.1
O365 logon cmdlets to assist IT administrators. In this module, there
are several cmdlets that simplify the process of logging onto various
O365 components.

Unable to contact server when I SSH into Powershell using an RSA key

I am working on a script that logs into a VM connected to my AD to perform some administrative functions. The script will be triggered by an application running on a Linux host. I've installed PowerShell Core and the Windows-Compatibility PowerShell module to allow me to log in via SSH. I can log in successfully and run the my script if I use a password, but if I log in using an RSA key, I get this error when I import AD:
Unable to contact the server. This may be because this server does not
exist, it is currently down, or it does not have the Active Directory
Web Services running.
CategoryInfo : ResourceUnavailable: (:) [Get-ADComputer], ADServerDownException
FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.GetADComputer
PSComputerName : localhost
The script on the Linux host looks something like this:
#!/bin/bash
ssh ad\\ad-user#windows-host-ip \
-o IdentitiesOnly=yes \
-i ./id_rsa \
"C:\\pwsh\\pwsh.exe -c C:\Users\ad-user\Scripts\ad-management-script.ps1"
And the ad-management-script.ps1 looks something like this:
Import-WinModule ActiveDirectory
Get-ADUser -Identity ad-user
Like I said before: This runs perfectly if I leave the key off and enter a password, but it hits the error I mentioned above if I use the key.
Other notes: Regardless of which method I use to log in, I get these values from the $env:
> $env:username
ad-user
> $env:userdomain
ad
Thanks in advance for any guidance.
As per brief googling looks like people are getting similar issues with ActiveDirectory module while remoting to Windows machine. Not sure suggested workarounds are applicable to your case though. However there are alternatives for using this module. Try options below and see if any of it works.
1. In Powershell (not core):
$user = "someuser"
$searchByUser = "(&(objectCategory=person)(objectClass=organizationalPerson)(samaccountname=$user))"
([adsisearcher]$searchByUser).FindOne().Properties
2. DSQUERY (In CMD, no need for powershell)
dsquery * -filter "samaccountname=someuser"
3. NET (in CMD)
net user SOMEUSER /domain
This is known as the double hop problem. We can not use keys which are used for authentication to remote VM , to authenticate AD server too. There are multiple option which you can use, here is the guide
https://learn.microsoft.com/en-us/powershell/scripting/learn/remoting/ps-remoting-second-hop?view=powershell-7.2

Add-AzureAccount : Index was out of range. Must be a non-negative and less than the size of the collection

On 4th of August a new version of the Azure powershell module (0.8.7.1) was released. In it is the ability to create credentials which you could then pass to the Add-AzureAccount function. Add-AzureAccount allows you to pull in an account to work with in the current PowerShell session.
$userName = "buildmaster#someaccount.onmicrosoft.com"
$securePassword = ConvertTo-SecureString -String "somepassword." -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($userName, $securePassword)
Add-AzureAccount -Credential $cred
This allowed me to get away from a popup window or messing with a settings file.
It seems to have stopped working! Both Add-AzureAccount (which pops up a window) and the credential based way. They now return an index was out of range issue.
Add-AzureAccount : Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
At S:\QA\Azure Scripts\cm-azure-helpers.psm1:1128 char:5
+ Add-AzureAccount
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Add-AzureAccount], ArgumentOutOfRangeException
+ FullyQualifiedErrorId : Microsoft.WindowsAzure.Commands.Profile.AddAzureAccount
Digging deeper with Fiddler shows that the OAuth call to the back end service seems to work. I get a token returned. But then I also get a 302 in the middle of the process stating that the page has moved. I don't know if that redirect was there when it was working previously or not.
Has anyone else experienced the Add-AzureAccount function just stop working like this? And more importantly - have you found a way around it?
Update - More info
I have now tried on several boxes under different azure accounts and seem to have the same results. I get a valid auth token returned with a redirect in the middle (not sure if that is an issue or not) and then get the index was out of range.
I have done this with the following variations:
PS:3 Azure Module: 0.8.6
PS:3 Azure Module: 0.8.7
PS:4 Azure Module: 0.8.6
PS:4 Azure Module: 0.8.7
I know exactly what caused this error for me, and how I worked around it (I thought I was the only one who had seen this :))
What had happened is that I had accidentally added a bogus/empty subscription to my account. And this empty subscription had been set to my "default" subscription.
Run "get-azuresubscription -default" to see what your default subscription is. You can then "remove" any junk subscriptions using "remove-azuresubscription" command.
You can then of course set a new azure subscription for your "default" using PS.
I actually reported this to the Azure PowerShell team now to get a better error message during this scenario.
Hopefully this solved your problem, it's possible other errors manifest the same error message.
If you do a fiddler trace, you should see that right after the login call (where PowerShell passes in your username/password, there should be 1 or multiple calls to GET /subscriptions.
Check the response to see whether there is anything suspicious there. Like, any of them return an empty body, empty array, subscription with id, name, etc..
I had a similar problem recently. The "fix" was for me was to delete the files at C:\Users[username]AppData\Roaming\Windows Azure Powershell (esp. the WindowsAzureProfile.xml file). The next time I ran Add-AzureAccount, the necessary files were created and all was well.
Please use:
Add-AzureRmAccount -SubscriptionId "id";
for login