PowerShell: System cannot find file when user not logged on - powershell

When I try to use Import-PfxCertificate I get an error when the user account I'm running the script with isn't logged on:
Import-PfxCertificate : The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
When I open an RDP session to the server the script runs at on that user account, it works without problems. The weird thing is that Test-Path $certfile -PathType Leaf returns true in both cases. What is going on?
Test-Path $certfile -PathType Leaf #always true
Import-PfxCertificate -FilePath $certfile -CertStoreLocation Cert:\CurrentUser\My -Password $Secure_String_Pwd
So the script is run as a background job on a timer on the server and when,
case 1: user account that is used to run the script has an active RDP session, the script runs fine.
case 2: user account that is used to run the script doesn't have an active RDP session, the script fails.
Edit: I found something in error[1].
New-Item : Could not find a part of the path 'C:\Users\Default\.Azure\AzInstallationChecks.json'.
At C:\Program Files\WindowsPowerShell\Modules\AzureRM.profile\5.8.2\StartupScripts\AzureRmError.ps1:17 char:9
What's this then?

I ran your command on my console, and I had no issues with the import. I am an admin on the machine that contains my console. I tried this with the powerShell session being elevated and non-elevated. Both worked.
$certfile = "C:\temp\cert.pfx"
$secure_string_pwd = convertto-securestring -string "password" -asplaintext -force
Import-PfxCertificate -FilePath $certfile -CertStoreLocation Cert:\CurrentUser\My -Password $Secure_String_Pwd
If this is not helpful at all, I will just delete this.

Try this piece of code and see it it works. Please post a complete exception if it doesn't work.
try
{
$Secure_String_Pwd = ConvertTo-SecureString 'DDDDD12345' -AsPlainText -Force
Import-PfxCertificate -FilePath 'C:\LocalPath\local.pfx' -CertStoreLocation Cert:\LocalMachine\My -Password $Secure_String_Pwd
$thumbprint = (Get-ChildItem -Path cert:\LocalMachine\my| Where-Object {$_.Subject -eq "CN=certificateNameWithoutextension"}).Thumbprint
# code for connect-Azure RM account
Connect-AzureRmAccount -ApplicationId $appid -CertificateThumbprint $thumbprint -Tenant $tenant -ServicePrincipal
}
catch
{
Write-Output $_
echo $_.Exception|format-list -force
}
Hope it helps.

It didn't help. The full exception is
PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\My
Thumbprint Subject
---------- -------
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX CN=derp
Connect-AzureRmAccount : The system cannot find the file specified.
At C:\temp\script.ps1:8 char:5
+ Connect-AzureRmAccount -ApplicationId $appid -CertificateThumbpri ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Connect-AzureRmAccount], Crypto
graphicException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Profile.ConnectAzureRmA
ccountCommand
Anyway, I went around the problem using C#.

Related

Start-Process : This command cannot be run due to the error: The filename or extension is too long

I want to configure the Outlook profile with the email account and I'm taking the values from the stored credentials. But when I run the script, it shows
Start-Process : This command cannot be run due to the error: The filename or extension is too long.
The code is as follows:
clear
if($process=(get-process 'outlook' -ErrorAction SilentlyContinue))
{
Write-Host "Outlook is running so close it.." -ForegroundColor Green
kill($process)
Write-Host "Outlook is stopped " -ForegroundColor Green
}
$reg="HKCU:\Software\Microsoft\Office\16.0\Outlook\Profiles"
Write-Host "create new profile for outlook" -ForegroundColor Green
"`n"
New-Item -Name "outlook" -Path $reg -Force -Verbose
Write-Host "New profile created" -ForegroundColor Green
"`n"
Write-Host "Launch outlook with newly created profile" -ForegroundColor Green
$Login = Get-StoredCredential -Target 'test'
$Decrypt = $Login.Password | ConvertFrom-SecureString
$Encrypt = $Decrypt | ConvertTo-SecureString -AsPlainText -Force
$passwd=[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($Encrypt))
$Password = ConvertTo-SecureString $passwd -AsPlainText -Force
$cred = new-object -Typename System.Management.Automation.pscredential -ArgumentList($Login.UserName, $password)
Start-Sleep -s 5
Start-Process 'OUTLOOK.EXE' -Credential $cred -ArgumentList '/profile "outlook" '
Error:
Start-Process : This command cannot be run due to the error: The filename or extension is too long.
At line:1 char:2
+ Start-Process 'OUTLOOK.EXE' -Credential $cred
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessComm
and
In this script, I'm able to create a new profile but unable to launch the outlook with newly created profile including the email account part.
The Start-process raises an error when providing Credentials - possible bug page has the following explanation to the problem:
When you use Start-Process without specifying a target directory with -WorkingDirectory, PowerShell's current location (directory) is used for the target process as well.
Since you're using -Credential to run as a different user - without elevation at that point - the target user may lack permission to access the current directory, which happens if the current directory is inside the current user's home directory subtree, for instance.
Unfortunately, PowerShell's error message obscures this cause by misleadingly reporting: The directory name is invalid.
The solution is to make sure that the current location is accessible to the target user, or, preferably, use the -WorkingDirectory parameter to explicitly set the target process's current directory.
For example, to start the target process from the directory in which a target script is located, you could use something like:
$script = 'c:\path\to\your\script.ps1'
Start-Process -WorkingDirectory (Split-Path $script) -Credential ...

Access Denied using Import-AzKeyVaultCertificate

I have a seemingly simple script for importing a PFX into Azure Key Vault. The service principal I am using is set to the Key Vault contributor role and has the access policies Get, List, Update, Create and Import. I am using certificate authentication when connecting the service principal. However, I get a very unhelpful error:
Import-AzKeyVaultCertificate : Access denied.
At line:1 char:1
+ Import-AzKeyVaultCertificate -VaultName $keyVault -Name 'AzureAuth' - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Import-AzKeyVaultCertificate], CryptographicException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.KeyVault.ImportAzureKeyVaultCertificate
My Script:
$PFX = "$env:TEMP\cert-lab.pfx"
$tenantID = 'xxx'
$AppID = 'xxx'
$keyVault = 'LabKV'
$assetName = 'AzureCert'
$EncryptPass = 'PFXpassword123'
## Clear the authentication context
Clear-AzContext -Force
$PFXPass = ConvertTo-SecureString -String $EncryptPass -AsPlainText -Force
$pfxCert = Import-PfxCertificate -FilePath $PFX -CertStoreLocation Cert:\CurrentUser\My -Password $PFXPass -Exportable
$ctx = Connect-AzAccount -ServicePrincipal -Tenant $tenantID -CertificateThumbprint $pfxCert.Thumbprint -ApplicationId $AppID
Import-AzKeyVaultCertificate -VaultName $keyVault -Name $assetName -FilePath $PFX -Password $PFXPass -DefaultProfile $ctx
Interestingly, if I manually import the cert through the console, I can use the exact same code with Get-AzKeyVaultCertificate instead of Import-AzKeyVaultCertificate and successfully retrieve the certificate. This tells me that the Service Principal at least has access to retrieve certificates. I'm still at a loss as to what is causing the Import to fail.
So I ended up buying a support plan and opening a case with Microsoft. Even though I was able to directly import cert-lab.pfx and was able to verify its contents with OpenSSL, for whatever reason, Import-AzKeyVaultCertificate just did not like the file. They had me create a new file by exporting from my CAPI store to cert2.pfx. The import command worked flawlessly with the new file. I shrugged my shoulders, deleted the old file and decided to move on with my life.

How to request a certificate from a CA on a remote machine using PowerShell?

I am trying to invoke a PowerShell command on a remote computer. I'd like to request a certificate from an in-house CA. If I run the following command directly on the remote PC the operation is successful:
Get-Certificate -Template 1.3.6.1.4.1.311.21.8.9612972.3074733.7357589.1249582.14248002.117.5480590.5436517 -Credential $cred -Url ldap: -CertStoreLocation Cert:\LocalMachine\My
When I run the following command from a remote computer on the same domain I get the WIN32: 87 error shown below. I have googled the error extensively and cannot figure out the issue (fyi.. I have mitigated the double hop issue earlier in my script by using Enable-WSManCredSSP).
$user = 'ABCCOmpany\<password>' #We are using the local machine's Administrator account
$password = ConvertTo-SecureString '<password>' -asplaintext -force
$credential = New-Object -typename System.Management.Automation.PSCredential -ArgumentList $user, $password
$RequestAndReceiveCertificateSuccessful = Invoke-Command -Session $s -ScriptBlock{param($cred) Get-Certificate -Template 1.3.6.1.4.1.311.21.8.9612972.3074733.7357589.1249582.14248002.117.5480590.5436517 -Credential $cred -Url ldap: -CertStoreLocation Cert:\LocalMachine\My} -ArgumentList $credential
Error:
The parameter is incorrect. 0x80070057 (WIN32: 87 ERROR_INVALID_PARAMETER)
+ CategoryInfo : NotSpecified: (:) [Get-Certificate], Exception
+ FullyQualifiedErrorId : System.Exception,Microsoft.CertificateServices.Commands.GetCertificateCommand
+ PSComputerName : Agent3

Copy-Item to networkpath: incorrect user name or password

I have a PowerShell v1 script, that is triggerd by a PLC. It should copy a file from the desktop of the embedded PC to a network path.
If I run the script manually it works just fine, but if the script is triggered by the PLC I will get the following error:
+ CategoryInfo : NotSpecified: (:) [Copy-Item], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.CopyItemCommand
copy-item : The user name or password is incorrect.
Any tips, why I get this error, would be very much appreciated!
Thanks for your help #TheIncorrigible1 after reading your comment I found the problem!
The problem was, that the script started by the plc runs with another user than the manually started script.
So the workaround is to first start powershell with the correct credentials with another script. For example like so:
$usr = 'XXX'
$paswrd = 'XXX'
$securePassword = ConvertTo-SecureString $paswrd -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $usr, $securePassword
$args = "/path to your script"
Start-Process powershell.exe -Credential $credential -ArgumentList ("-file $args")
downside... password in plain text...

Connect-MsolService over WinRM fails

I am running a simple Powershell script over WinRM in order to get from Azure AD the list of user's licences. Here is the script itself:
$username = "admin#domain.onmicrosoft.com"
$password = "secret"
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $(convertto-securestring $password -AsPlainText -Force)
Import-Module MSOnline
Connect-MsolService -Credential $cred -Verbose
$user = Get-MsolUser -UserPrincipalName $username
$status = $user.Licenses | ForEach-Object { $_.ServiceStatus }
$status | ForEach-Object { $_.ServicePlan.ServiceName + "|" + $_.ProvisioningStatus }
I have installed both Microsoft Online Services Sign-In Assistant and Azure Active Directory Module for PowerShell as described on this page https://technet.microsoft.com/en-us/library/jj151815.aspx#bkmk_installmodule
The script works fine if I run it locally on a machine running Windows.
But once I try to run it from Linux machine over WinRM the following exception is raised:
Connect-MsolService : Exception of type
'Microsoft.Online.Administration.Automation.MicrosoftOnlineException' was
thrown.
At line:5 char:1
+ Connect-MsolService -Credential $cred -Verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [Connect-MsolService], Mic
rosoftOnlineException
+ FullyQualifiedErrorId : 0x80070005,Microsoft.Online.Administration.Autom
ation.ConnectMsolService
However, if I run the script at least once locally on a Windows machine it starts working over WinRM. But after I reboot Windows it stops working again.
I have a strong feeling that when I run the script locally some background process is started and after that everything starts working over WinRM. But I could not identify what the process is.
I have installed Sing-In Assistant version 7.250.4556.0 (2/17/2014), Azure AD Module version 1.0.0 (1/19/2015).
It is very inconvenient to run the script locally each time Windows is restarted, so any help is appreciated.