Forum Discussion

Philip Harrison's avatar
Philip Harrison
Brass Contributor
Apr 22, 2024

PowerShell cmdlets not available within a script unless it is run as administrator

I wonder if somebody can help with this issue. Essentially I want to be able to connect to Exchange Online and the Security and Compliance PowerShell from within a script run as a regular user, not administrator.

If I drop these commands into my un-elevated PS window they will connect successfully and give me back some info on the two commands. If I drop the same commands into a PS1 file and execute it in an elevated PS console they also run successfully.

 

 

Connect-IPPSSession
Get-Command Get-DlpCompliancePolicy
Connect-ExchangeOnline
Get-Command Get-Mailbox

 

 

 

 

If I run Get-ConnectionInformation in the script I can see the two connections are there -

 

ConnectionId                    : 745f6176-5d1f-46ec-a786-b8e84f273791
State                           : Connected
Id                              : 1
Name                            : ExchangeOnlineProtection_1
UserPrincipalName               : *********
ConnectionUri                   : https://eur01b.ps.compliance.protection.outlook.com
AzureAdAuthorizationEndpointUri : https://login.microsoftonline.com/organizations
TokenExpiryTimeUTC              : 20/04/2024 10:01:24 +00:00
CertificateAuthentication       : False
ModuleName                      : C:\Users\*******\AppData\Local\Temp\tmpEXO_5lnrtren.etr
ModulePrefix                    :
Organization                    :
DelegatedOrganization           :
AppId                           :
PageSize                        : 1000
TenantID                        : 081cc50b-e5a5-4e76-b6b7-d7c274899193
TokenStatus                     : Active
ConnectionUsedForInbuiltCmdlets : False
IsEopSession                    : True

ConnectionId                    : 3d3547ec-f35e-4dc3-ba50-ed2f93ef0c35
State                           : Connected
Id                              : 2
Name                            : ExchangeOnline_2
UserPrincipalName               : *******
ConnectionUri                   : https://outlook.office365.com
AzureAdAuthorizationEndpointUri : https://login.microsoftonline.com/organizations
TokenExpiryTimeUTC              : 20/04/2024 11:50:29 +00:00
CertificateAuthentication       : False
ModuleName                      : C:\Users\*******\AppData\Local\Temp\tmpEXO_a2axh3gk.iwh
ModulePrefix                    :
Organization                    :
DelegatedOrganization           :
AppId                           :
PageSize                        : 1000
TenantID                        : 081cc50b-e5a5-4e76-b6b7-d7c274899193
TokenStatus                     : Active
ConnectionUsedForInbuiltCmdlets : True
IsEopSession                    : False

 

 

 

If I run Get-Module I can see the modules I understand are necessary -

 

Name              : ExchangeOnlineManagement
Path              : C:\Program Files\WindowsPowerShell\Modules\ExchangeOnlineManagement\3.4.0\netFramework\ExchangeOnli
                    neManagement.psm1
Description       : This is a General Availability (GA) release of the Exchange Online Powershell V3 module. Exchange
                    Online cmdlets in this module are REST-backed and do not require Basic Authentication to be
                    enabled in WinRM. REST-based connections in Windows require the PowerShellGet module, and by
                    dependency, the PackageManagement module.
                    Please check the documentation here - https://aka.ms/exov3-module.
                    For issues related to the module, contact Microsoft support.
Guid              : b5eced50-afa4-455b-847a-d8fb64140a22
Version           : 3.4.0
ModuleBase        : C:\Program Files\WindowsPowerShell\Modules\ExchangeOnlineManagement\3.4.0
ModuleType        : Script
PrivateData       : {PSData}
AccessMode        : ReadWrite
ExportedAliases   : {}
ExportedCmdlets   : {[Add-VivaModuleFeaturePolicy, Add-VivaModuleFeaturePolicy], [Get-ConnectionInformation,
                    Get-ConnectionInformation], [Get-DefaultTenantBriefingConfig, Get-DefaultTenantBriefingConfig],
                    [Get-DefaultTenantMyAnalyticsFeatureConfig, Get-DefaultTenantMyAnalyticsFeatureConfig]...}
ExportedFunctions : {[Connect-ExchangeOnline, Connect-ExchangeOnline], [Connect-IPPSSession, Connect-IPPSSession],
                    [Disconnect-ExchangeOnline, Disconnect-ExchangeOnline]}
ExportedVariables : {}
NestedModules     : {Microsoft.Exchange.Management.RestApiClient,
                    Microsoft.Exchange.Management.ExoPowershellGalleryModule}

Name              : Microsoft.PowerShell.Management
Path              : C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Management\Microsoft.PowerS
                    hell.Management.psd1
Description       :
Guid              : eefcb906-b326-4e99-9f54-8b4bb6ef3c6d
Version           : 3.1.0.0
ModuleBase        : C:\Windows\System32\WindowsPowerShell\v1.0
ModuleType        : Manifest
PrivateData       :
AccessMode        : ReadWrite
ExportedAliases   : {[gcb, gcb], [gin, gin], [gtz, gtz], [scb, scb]...}
ExportedCmdlets   : {[Add-Computer, Add-Computer], [Add-Content, Add-Content], [Checkpoint-Computer,
                    Checkpoint-Computer], [Clear-Content, Clear-Content]...}
ExportedFunctions : {}
ExportedVariables : {}
NestedModules     : {Microsoft.PowerShell.Commands.Management.dll}

Name              : Microsoft.PowerShell.Utility
Path              : C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShel
                    l.Utility.psd1
Description       :
Guid              : 1da87e53-152b-403e-98dc-74d7b4d63d59
Version           : 3.1.0.0
ModuleBase        : C:\Windows\System32\WindowsPowerShell\v1.0
ModuleType        : Manifest
PrivateData       :
AccessMode        : ReadWrite
ExportedAliases   : {[CFS, CFS], [fhx, fhx]}
ExportedCmdlets   : {[Add-Member, Add-Member], [Add-Type, Add-Type], [Clear-Variable, Clear-Variable],
                    [Compare-Object, Compare-Object]...}
ExportedFunctions : {[ConvertFrom-SddlString, ConvertFrom-SddlString], [Format-Hex, Format-Hex], [Get-FileHash,
                    Get-FileHash], [Import-PowerShellDataFile, Import-PowerShellDataFile]...}
ExportedVariables : {}
NestedModules     : {Microsoft.PowerShell.Commands.Utility.dll, Microsoft.PowerShell.Utility}

Name              : PSReadLine
Path              : C:\Program Files\WindowsPowerShell\Modules\PSReadLine\2.0.0\PSReadLine.psm1
Description       : Great command line editing in the PowerShell console host
Guid              : 5714753b-2afd-4492-a5fd-01d9e2cff8b5
Version           : 2.0.0
ModuleBase        : C:\Program Files\WindowsPowerShell\Modules\PSReadLine\2.0.0
ModuleType        : Script
PrivateData       :
AccessMode        : ReadWrite
ExportedAliases   : {}
ExportedCmdlets   : {[Get-PSReadLineKeyHandler, Get-PSReadLineKeyHandler], [Get-PSReadLineOption,
                    Get-PSReadLineOption], [Remove-PSReadLineKeyHandler, Remove-PSReadLineKeyHandler],
                    [Set-PSReadLineKeyHandler, Set-PSReadLineKeyHandler]...}
ExportedFunctions : {[PSConsoleHostReadLine, PSConsoleHostReadLine]}
ExportedVariables : {}
NestedModules     : {Microsoft.PowerShell.PSReadLine}

Name              : tmpEXO_5lnrtren.etr
Path              : C:\Users\******\AppData\Local\Temp\tmpEXO_5lnrtren.etr\tmpEXO_5lnrtren.etr.psm1
Description       : This is a Powershell module generated by using the AutoGEN infra.
Guid              : 2c604488-886e-4090-ac70-2b9a3130c449
Version           : 1.0
ModuleBase        : C:\Users\********\AppData\Local\Temp\tmpEXO_5lnrtren.etr
ModuleType        : Script
PrivateData       : {PSData}
AccessMode        : ReadWrite
ExportedAliases   : {}
ExportedCmdlets   : {}
ExportedFunctions : {[Add-ComplianceCaseMember, Add-ComplianceCaseMember], [Add-eDiscoveryCaseAdmin,
                    Add-eDiscoveryCaseAdmin], [Add-RoleGroupMember, Add-RoleGroupMember], [Cancel-DlpEdmSession,
                    Cancel-DlpEdmSession]...}
ExportedVariables : {[HelpFileNames, System.Management.Automation.PSVariable]}
NestedModules     : {}

Name              : tmpEXO_a2axh3gk.iwh
Path              : C:\Users\*******\AppData\Local\Temp\tmpEXO_a2axh3gk.iwh\tmpEXO_a2axh3gk.iwh.psm1
Description       : This is a Powershell module generated by using the AutoGEN infra.
Guid              : e84305bc-e9b9-45bd-bb9f-d38a411419b2
Version           : 1.0
ModuleBase        : C:\Users\********\AppData\Local\Temp\tmpEXO_a2axh3gk.iwh
ModuleType        : Script
PrivateData       : {PSData}
AccessMode        : ReadWrite
ExportedAliases   : {}
ExportedCmdlets   : {}
ExportedFunctions : {[Add-AvailabilityAddressSpace, Add-AvailabilityAddressSpace], [Add-DistributionGroupMember,
                    Add-DistributionGroupMember], [Add-MailboxFolderPermission, Add-MailboxFolderPermission],
                    [Add-MailboxLocation, Add-MailboxLocation]...}
ExportedVariables : {[HelpFileNames, System.Management.Automation.PSVariable]}
NestedModules     : {}

 

 

And once the script exits, I can then do 'Get-Command Get-Mailbox' and get a good response. So the connection is clearly working, the script just cannot seem to access the functions/cmdlets while it is running. This is Twilight Zone stuff right!?

 

I do not know if it's relevant, but we use AppLocker. So in my unelevated PS session I am in ConstrainedLanguage mode, but the script is excluded from AppLocker so executes in FullLanguage mode.

 

I feel like I'm missing something fundamental about how PS sessions or scopes operate within a script run as admin vs a regular user, or is there a bug in Connect-ExchangeOnline, but no amount of Google searching has saved my mind yet!

 

Thanks

Resources