InvalidCastException when trying to obtain UserPrincipal.Current - powershell

I have a PowerShell script which checks the currently signed in user as part of its start-up process. I'm using .Net to do this by adding the assembly:
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$cUser = [System.DirectoryServices.AccountManagement.UserPrincipal]::Current
For almost everyone this works fine and I get a UserPrincipal object that I can use elsewhere, however there are a couple of users who get the following error when running it:
Unable to cast object of type 'System.DirectoryServices.AccountManagement.GroupPrincipal' to type 'System.DirectoryServices.AccountManagement.UserPrincipal'. At line:2 char:1
+ [System.DirectoryServices.AccountManagement.UserPrincipal]::Current
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], InvalidCastException
+ FullyQualifiedErrorId : System.InvalidCastException
This is on a standard Windows 10 20H2 install and doesn't matter if PowerShell is running elevated or not. I've never seen this call return anything other than a UserPrincipal before, so I would be grateful for any advice: is this something I can deal with in code, or is there some underlying issue with the machines that are returning this exception?

I don't know if this is what you're looking for:
$cUser = Get-ADUser $Env:Username -Properties *
This has the most important attributes that you can use for whatever you want later on. It provides as much attribute as the code you posted that didn't work for some of the user.

Related

PowerShell Import-GPO: Operation not valid

Afternoon everyone. I'm running into an issue I'm not sure how to handle. I'm working on a script for work to deploy a Domain Controller using PSremoting. It all works well in fine until I get to where I'm importing some GPOs from backups.
*All the commands are run under invoke-command
I run the command Import-GPO -BackUpName $GPO -TargetName $GPO -Path $GPOPath -MigrationTable $MigTable -CreateIfNeeded
When I run this, I get an error on the host:
Operation is not valid due to the current state of the object.
+ CategoryInfo : NotSpecified: (:) [Import-GPO], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.GroupPolicy.Commands.ImportGpoCommand
+ PSComputerName : v204-DC1
I can't seem to find anything that says what this means. When I check for the GPOs on the DC, they all show up and seem to be linked properly. I am curious what this error is, or if I should just append -ErrorAction SilentlyContinue to the end of my code.
Ended up being an issue with my migration table. I rolled back to an earlier one and ended up being good to go

The start-process cmdlet of powershell will fail with -PassThru argument when trying to launch Edge browser

In my test script by powershell, I'd start an Edge browser and get it's main process's ID. Simply like this:
$edge = Start-Process microsoft-edge: www.ted.com -PassThru
but instead of able to get the process id from $edge.Id, I've got error message like this:
Start-Process : This command cannot be run completely because the system cannot find all the information required.
At line:1 char:7
+ $edge=Start-Process microsoft-edge: www.ted.com -PassThru
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
Is there any simple and straightforward way to really doing this without enumerate and check the process list?
Thanks!
I try to test your script and I am getting a similar error as yours.
Based on my search result, passthru is not one of the common parameters, and it does not exist everywhere.
Reference:
Use the PowerShell Passthru Parameter and Get Back Objects
I think it is not available for the MS Edge browser and that's why the script gives an error.
I try to search for an alternative command for PassThru but I did not get any helpful information about it.
In this situation, it is better to enumerate and check the process list

PowerShell Script with Clixml and Taskscheduler

Here's the problem:
When I run my PowerShell script manually, everything works fine. But it doesn't work via task scheduling.
The reason is probably my stored credentials for Active Directory and Mobile Device Management.I stored them with "Export-Clixml" but the xml files cant be read when i open the script with task scheduler. Without it works perfect.
The task scheduler is executed with the same user who saved the credentials in the XML before.
I hope you understand what I mean.
Edit 1:
I've tried the Solution from "Bender the Greatest".
Unfortunately it still doesn't work. I exported my credentials with "Export-Clixml" and import them with "Import-Clixml".
It doesn't matter if I generate them manually via my admin account or via the system account (with psexec). If I then execute it via the corresponding account with which the credentials were generated, it still doesn't work.
But it seems to find the credentials (I saw that in the log). But The import doesn't seem to work.
If I manually include the credentials in the script it works fine, but I would have liked to store them encrypted.
[Lizenzauswertung] Überprüfe Zugangsdaten
[Lizenzauswertung] MDM Zugangsdaten gefunden - Credentials found
[Lizenzauswertung] MDM AccessToken gefunden - Credentials found
[Lizenzauswertung] AD Zugangsdaten gefunden - Credentials found
Here im trying to decrypt the Password from the XML File:
It is not possible to call a method for an expression that has NULL.(Translated)
In C:\Scripts\ADAuswertung\AD_Auswertung_GKZ.ps1:171 Zeichen:1
+ $PSCPW = $CredsMDM.GetNetworkCredential().Password
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
It is not possible to call a method for an expression that has NULL.(Translated)
In C:\Scripts\ADAuswertung\AD_Auswertung_GKZ.ps1:171 Zeichen:1
+ $PSCPW = $CredsMDM.GetNetworkCredential().Password
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
This is a replacement for the username to have the right spelling for a webrequest:
It is not possible to call a method for an expression that has NULL.(Translated)
In C:\Scripts\ADAuswertung\AD_Auswertung_GKZ.ps1:172 Zeichen:1
+ $RPSCUser = $PSCUser.Replace("INTRA","intra.lan")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
It is not possible to call a method for an expression that has NULL.(Translated)
In C:\Scripts\ADAuswertung\AD_Auswertung_GKZ.ps1:172 Zeichen:1
+ $RPSCUser = $PSCUser.Replace("INTRA","intra.lan")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Here you can see the errors that occur when importing the MDM credentials. The reason for the errors is described above. I edit the credentials after importing them before they are passed to the script.
The MDM Access Token is not encrypted and can be read.
The AD credentials are not processed beforehand, but passed directly to the AD commands. Therefore, no error is displayed here. Since it does not finish the AD report, which I saw in the log, these are not imported either.
Here is a little Codesnippet of the Import/Export. Just got the code here for the MDM credentials. The other queries are the same.
If (Test-Path $CredentialsMDM){
$CredsMDM = Import-Clixml -Path $CredentialsMDM
Write-Host "[Lizenzauswertung] MDM Zugangsdaten gefunden" -ForegroundColor Green
} else {
Write-Host "[Lizenzauswertung] MDM Zugangsdaten nicht gefunden" -ForegroundColor Yellow
Get-Credential -Message "Zugangsdaten für MDM / Airwatch" | export-clixml -path $CredentialsMDM
$CredsMDM = Import-Clixml -Path $CredentialsMDM
}
Write-Host "[Lizenzauswertung] Zugangsdaten überprüft" -ForegroundColor Green
$PSCUser = $CredsMDM.UserName
$PSCPW = $CredsMDM.GetNetworkCredential().Password
$RPSCUser = $PSCUser.Replace("INTRA","intra.lan")
$AccessToken = $CredsMDMAT.accesstoken
$Auth = $CredsAD
(I am sorry for the spaghetti code.)
You need to provide the error you're getting but I'm going to take a shot in the dark here. I'm guessing you're either exporting secretAD.xml as one user and running your script as another user from Task Scheduler, or exporting secretAD.xml on another computer/server. By default, credentials are able to be decrypted only by the user that built it on that specific server. This is how Windows' Data Protection API (DPAPI) works.
The easy way to fix this is to generate secretAD.xml as the user you intend to run the script as. You can specify your own key for decryption, which can be used by any user on any box, but you will need to figure out a method of secure delivery of the decryption key to the runtime. If you want/need to run the script as NT Authority\SYSTEM, I recommend using psexec to open an interactive SYSTEM Powershell session, generate the credential, and then use Export-CliXml to serialize the credential to secretAD.xml.
Note that the default DPAPI key gets changed when an account password is rotated, so you'll need to remember to rebuild the credential when that happens.
I've found the solution to my problem.
The reason was that the path to the credentials was ".\secretMDM.xml".
The task scheduler executes the script at a different location.
Therefore I had to specify the whole path of the file.
Thanks for the help anyway.
Edit:
Out of interest I created the "Credential" - XML files with the Task Scheduler. Have a look where it stores the files ;)

ADAL in Azure Automation: Type not loading intermittantly

I'm working on an Azure Automation script where I need to retrieve an access token to call the AAD Graph API. I wanted to use ADAL to do this so I zipped up Microsoft.IdentityModel.Clients.ActiveDirectory.dll and uploaded it as a module. When I run from the test blade, it sometimes works, and sometimes fails with this error:
New-Object : Cannot find type [Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential]: verify that the
assembly containing this type is loaded.
At line:22 char:9
+ $cred = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredent ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
When it fails I just run it again and it works. Now I've published and scheduled this runbook as a daily job 3 days ago. So far it has failed every day with this same error.
Has any one else seen this? Any suggestions on next steps?
I fixed this by adding the following line to my script:
Add-Type -Path "C:\Modules\User\Microsoft.IdentityModel.Clients.ActiveDirectory\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
Still not sure why it was working intermittently before. I guess depending on what else was going on ADAL may or may not have been loaded?

Windows RT Powershell (PermissionDenied) on New-Object

I am trying to instantiate an object in Powershell for Windows RT, but keep getting the following error.
PS > $foo = New-Object System.Security.Cryptography.SHA1Managed
New-Object : Cannot create type. Only core types are supported in this language mode.
At line:1 char:8
+ $foo = New-Object System.Security.Cryptography.SHA1Managed
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (:) [New-Object], PSNotSupportedException
+ FullyQualifiedErrorId : CannotCreateTypeConstrainedLanguage,Microsoft.PowerShell.Commands.NewObjectCommand
I just spent the last thirty minutes engaged in some pretty heavy Google-fu and was unable to find anything even close to a similar problem, let alone an answer. My hope is that I just need to configure something; my fear is that Windows RT ships with a crippled version of Powershell.
Does anyone know which case it is?
Yup, Windows RT ships with a locked down version of PowerShell - it operates in ConstrainedLanguageMode which prevents most interaction (prop setters/method calls) with .NET. It also has a limited command set IIRC.