powershell code signing: Set-AuthenticodeSignature : Cannot bind parameter 'Certificate'. Cannot convert value - powershell

Trying to create a self-signed code signing certificate that I can use to sign powershell scripts... Looks like it works except when I try to use the certificate to sign a powershell scriptit gives me the Error "Set-AuthenticodeSignature : Cannot bind parameter 'Certificate'. Cannot convert value "
Here's the code that reproduces the problem:
# FILE: new_code_signing_cert.ps1
param(
[switch]$trace
)
try {
if ($trace) {
Set-PSDebug -Trace 1
}
$base = "wpmoore_code_signing";
$password = "password123";
$outdir = ".\cert"
$splat = #{
Subject = "CN=Script Automation,E=myemail#gmail.com,O=My Name"
FriendlyName = "$base"
NotAfter = (Get-Date).AddYears(3)
CertStoreLocation = "Cert:\CurrentUser\My"
Type = "CodeSigningCert"
}
write-host "Creating Code Signing Certificate...`n"
$cert = New-SelfSignedCertificate #splat
$cthumb = $cert.Thumbprint
$cpath = "Cert:\CurrentUser\My\$cthumb"
# Backup Certificate with password
$encrypted = ConvertTo-SecureString -String $password -Force -AsPlainText
new-Item -Path $outdir -Type Directory -ErrorAction SilentlyContinue | out-null
$pfx_file = "${outdir}\${base}.${cthumb}.pfx"
Export-PfxCertificate -Cert:$cpath -FilePath:$pfx_file -Password $encrypted | out-null
write-host "Certificate Location : $cpath"
write-host "Certificate Backup : $pfx_file"
# Dir of CertStoreLocation
#Get-ChildItem $cpath
Set-AuthenticodeSignature -Certificate $cpath -FilePath .\new_code_signing_cert.ps1
}
finally {
Set-PSDebug -Trace 0
write-host ""
}
Hwere's what happens when I run...
PS> new_code_signing_cert.ps1
Set-AuthenticodeSignature : Cannot bind parameter 'Certificate'. Cannot convert value
"Cert:\CurrentUser\My\C4C3179BAB17C20F33D3D0E23CF88CF500CDBD68" to type
"System.Security.Cryptography.X509Certificates.X509Certificate2". Error: "The given path's format is not
supported."
At line:1 char:40
+ ... Certificate Cert:\CurrentUser\My\C4C3179BAB17C20F33D3D0E23CF88CF500CD ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-AuthenticodeSignature], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.SetAuthenticodeSig
natureCommand

Re-Loading certificate using Cert path:
$cert2 = Get-ChildItem -Path $cpath -CodeSigningCert
Re-Loading certificate from pfx file:
$cert2 = Get-PfxCertificate -FilePath $pfx_file
Once you have the certificate loaded:
Set-AuthenticodeSignature -Certificate $cert2 -FilePath script.ps1
Or use the certificate already loaded:
Set-AuthenticodeSignature -Certificate $cert -FilePath script.ps1

Related

Powershell AzureAD App Registration Permissions New-AzureADApplication -RequiredResourceAccess

I am having a problem with the following code. I am trying to assign the following permissions to an App Registration in AzureAD using the -RequiredResourceAccess property from New-AzureADApplication. I keep getting an invalid value for $reqGraph?
Please help?
New-AzureADApplication : Error occurred while executing NewApplication
Code: Request_BadRequest Message: Invalid value specified for property
'resourceAppId' of resource 'RequiredResourceAccess'. RequestId:
5abf5ea5-8f94-4d14-8e8d-8f12a92bf3e5 DateTimeStamp: Mon, 17 May 2021
07:12:02 GMT Details: PropertyName - resourceAppId, PropertyErrorCode
InvalidValue HttpStatusCode: BadRequest HttpStatusDescription: Bad Request HttpResponseStatus: Completed
$appName = "Test" # Maximum 32 characters
$adalUrlIdentifier = "https://abc.dk/AADGuestLifecycleMgmt"
$appReplyUrl = "https://www.abc.dk"
$pwd = Read-Host -Prompt 'Enter a secure password for your certificate!'
$certStore = "Cert:\CurrentUser\My"
$currentDate = Get-Date
$endDate = $currentDate.AddYears(10) # 10 years is nice and long
$thumb = (New-SelfSignedCertificate -DnsName "abc.dk" -CertStoreLocation $certStore -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $endDate).Thumbprint
$thumb > cert-thumb.txt # Save to file
$pwd = ConvertTo-SecureString -String $pwd -Force -AsPlainText
Export-PfxCertificate -cert "$certStore\$thumb" -FilePath .\AzureADGuestLifecycleMgmt.pfx -Password $pwd
$path = (Get-Item -Path ".\").FullName
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("$path\AzureADGuestLifecycleMgmt.pfx", $pwd)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())
Install-Module AzureAD
Import-Module AzureAD
# Connect to Azure AD as an admin account
Connect-AzureAD
# Store tenantid
$tenant = Get-AzureADTenantDetail
$tenant.ObjectId > tenantid.txt
# Add AuditLog.Read.All access
$svcPrincipal = Get-AzureADServicePrincipal -All $true | ? { $_.DisplayName -match "Microsoft Graph" }
$appRole = $svcPrincipal.AppRoles | ? { $_.Value -eq "AuditLog.Read.All" }
$appPermission = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "$($appRole.Id)", "Role"
#Add Directory.ReadWrite.All access
$appRole2 = $svcPrincipal.AppRoles | ? { $_.Value -eq "Directory.ReadWrite.All" }
$appPermission2 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "$($appRole2.Id)", "Role"
$reqGraph = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
$reqGraph.ResourceAppId = $svcPrincipal.AppId
$reqGraph.ResourceAccess = $appPermission, $appPermission2
Write-Host $reqGraph
# Create Azure Active Directory Application (ADAL App)
$application = New-AzureADApplication -DisplayName "$appName" -IdentifierUris $adalUrlIdentifier -ReplyUrls $appReplyUrl -RequiredResourceAccess $reqGraph
New-AzureADApplicationKeyCredential -ObjectId $application.ObjectId -CustomKeyIdentifier "$appName" -Type AsymmetricX509Cert -Usage Verify -Value $keyValue -StartDate $currentDate -EndDate $endDate.AddDays(-1)
It seems that there are more than one app registration whose name includes "Microsoft Graph" in your tenant. It causes you to get the wrong $svcPrincipal.AppId (in this case, it may be a combination of multiple app ids).
Please directly set $reqGraph.ResourceAppId = "00000003-0000-0000-c000-000000000000".
00000003-0000-0000-c000-000000000000 is the app id of the Microsoft Graph app, which is a fixed value.
Here is the correct code with $_.DisplayName -eq "Microsoft Graph"
appName = "Test" # Maximum 32 characters
$adalUrlIdentifier = "https://abc.dk/AADGuestLifecycleMgmt"
$appReplyUrl = "https://www.abc.dk"
$pwd = Read-Host -Prompt 'Enter a secure password for your certificate!'
$certStore = "Cert:\CurrentUser\My"
$currentDate = Get-Date
$endDate = $currentDate.AddYears(10) # 10 years is nice and long
$thumb = (New-SelfSignedCertificate -DnsName "abc.dk" -CertStoreLocation $certStore -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $endDate).Thumbprint
$thumb > cert-thumb.txt # Save to file
$pwd = ConvertTo-SecureString -String $pwd -Force -AsPlainText
Export-PfxCertificate -cert "$certStore\$thumb" -FilePath .\AzureADGuestLifecycleMgmt.pfx -Password $pwd
$path = (Get-Item -Path ".\").FullName
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("$path\AzureADGuestLifecycleMgmt.pfx", $pwd)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())
Install-Module AzureAD
Import-Module AzureAD
# Connect to Azure AD as an admin account
Connect-AzureAD
# Store tenantid
$tenant = Get-AzureADTenantDetail
$tenant.ObjectId > tenantid.txt
# Add AuditLog.Read.All access
$svcPrincipal = Get-AzureADServicePrincipal -All $true | ? { $_.DisplayName -eq "Microsoft Graph" }
$appRole = $svcPrincipal.AppRoles | ? { $_.Value -eq "AuditLog.Read.All" }
$appPermission = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "$($appRole.Id)", "Role"
#Add Directory.ReadWrite.All access
$appRole2 = $svcPrincipal.AppRoles | ? { $_.Value -eq "Directory.ReadWrite.All" }
$appPermission2 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "$($appRole2.Id)", "Role"
$reqGraph = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
$reqGraph.ResourceAppId = $svcPrincipal.AppId
$reqGraph.ResourceAccess = $appPermission, $appPermission2
Write-Host $reqGraph
# Create Azure Active Directory Application (ADAL App)
$application = New-AzureADApplication -DisplayName "$appName" -IdentifierUris $adalUrlIdentifier -ReplyUrls $appReplyUrl -RequiredResourceAccess $reqGraph
New-AzureADApplicationKeyCredential -ObjectId $application.ObjectId -CustomKeyIdentifier "$appName" -Type AsymmetricX509Cert -Usage Verify -Value $keyValue -StartDate $currentDate -EndDate $endDate.AddDays(-1)

how to use Convert-PemToPfx in Azure automation account?

Im trying to generate pfx from the pem and key file stored in azure keyvualt from azure powershell automation account. I can generate a pfx with the same key and pem file using openssl but when I try the same in powershell I'm getting an error "Convert-PemToPfx : Exception setting "PrivateKey": "The public key of the certificate does not match the value
specified."".
$secretpem = Get-AzureKeyVaultSecret -VaultName '$vaultname' -Name 'secret-pem'
$secretkey = Get-AzureKeyVaultSecret -VaultName '$vaultname' -Name 'secret-key'
$pem = "certificate.pem"
$secretpem.SecretValueText | Out-File -FilePath $pem
$key = "certificate.key"
$secretkey.SecretValueText | Out-File -FilePath $key
$password = ConvertTo-SecureString "P#ssW0rD!" -asplaintext -for
#Get-Content -Path certificate.pem
#Get-Content -Path certificate.key
Import-Module -Name PSPKI
Convert-PemToPfx -InputPath certificate.pem -KeyPath certificate.key -OutputPath certificate.pfx -
Password $password

Powershell uploading files to SharePoint : Exception calling "ExecuteQuery" with "0" argument(s) error

I want to upload all .csv files from a C:/ to SharePoint. The script runs up to $Ctx.ExecuteQuery() and returns this error. I am able to run other PowerShell scripts on the site, and am the site owner, I suspect it is something other than access privileges.
Where do I start looking ?
Exception calling "ExecuteQuery" with "0" argument(s): "The remote server returned an error: (403) Forbidden."
+ $Ctx.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException
Get-ChildItem "c:\users\xxx\downloads" -Filter *.csv | % {
$eachFile =Get-ChildItem "c:\users\xxxx\downloads\" -Filter *.csv
$eachFile | ForEach-Object{
#parameters
$SiteURL = "https://xxx.sharepoint.com/sites/nrg"
$LibraryName="Audit History"
$UserName = "xxxx#x.onmicrosoft.com"
$Password = "xx"
$SecurePassword= $Password | ConvertTo-SecureString -AsPlainText -Force
#Setup the Context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
$Ctx.Credentials = $Credentials
#Get the Library
$Library = $Ctx.Web.Lists.GetByTitle($LibraryName)
#Get the file from disk
$FileStream = ([System.IO.FileInfo] (Get-Item $OutputFile)).OpenRead()
#Get File Name from source file path
$SourceFileName = Split-path $eachFile -leaf
#sharepoint online upload file powershell
$FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.ContentStream = $FileStream
$FileCreationInfo.URL = $SourceFileName
$FileUploaded = $Library.RootFolder.Files.Add($FileCreationInfo)
#powershell upload single file to sharepoint online
$Ctx.Load($FileUploaded)
$Ctx.ExecuteQuery()
#Close file stream
$FileStream.Close()
write-host "File has been uploaded!"
}
}
Solution was to remove the Credentials to before the ForEach-Object.

Getting below error on running PowerShell script

I am using one PowerShell script to download content (a zip file) from a website which requires credentials to get authenticated for the website. Also, have used proxy and proxy credentials since it is an authenticated proxy. I am getting an error which I have pasted below.
I have tried giving the proxy and proxy credentials but no luck.
I have bypassed the execution policy using Powershell -ExecutionPolicy Bypass.
When I try accessing the website from my browser then I am able to access the zip file.
Please find the code snippet below:
#Path to Save data
$tipath = "C:\Somepath"
$localpath = "\somefile.zip"
$timepath = "\Zip_file.txt"
$unzippath = "\Someotherpath"
$storepath = $tipath + $localpath
$remotefilepath = $tipath + $timepath
$unzipfolder = $tipath + $unzippath
# Create Folder If Not Exists #
$FolderToCreate = $tipath
if (!(Test-Path $FolderToCreate -PathType Container)) {
New-Item -ItemType Directory -Force -Path $FolderToCreate
}
#Downloading File #
$username = "username"
$password = "Password" | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($username, $password)
$secPasswd = "password123" | ConvertTo-SecureString -AsPlainText -Force
$wc = New-Object System.Net.WebClient
$wc.Credentials = New-Object System.Net.NetworkCredential("domain\user", $secPasswd)
# get remote file info
Invoke-WebRequest -Proxy "http://x.x.x.x:8080" -ProxyCredential $myCreds -Uri "https://somewebsite/checksum.txt" -OutFile $remotefilepath -Credential $cred
$remotefile = Get-Content -Path $remotefilepath
Write-Host Remote File Hash : $remotefile
# if the file exists already
if (Test-Path $storepath) {
# get local file info
$localfile = (Get-FileHash $storepath -Algorithm SHA256).Hash
Write-Host Local File Hash : $localfile
# if the remote file is newer than the local file
if ($remotefile -ne $localfile) {
Invoke-WebRequest -Proxy "http://x.x.x.x:8080" -ProxyCredential $myCreds -Uri "https://somewebsite/checksum.txt" -OutFile $remotefilepath -Credential $cred
Invoke-WebRequest -Proxy "http://x.x.x.x:8080" -ProxyCredential $myCreds -Uri "https://somewebsite/somezipfile.zip" -OutFile $storepath -Credential $cred
This code should check the hash and download directly download the zip file from the website and unzip it.
If it can download in the zip file then the later part I can troubleshoot.
PS C:\Users\Administrator\Desktop> powershell -ExecutionPolicy ByPass -File C:\Users\Administrator\Desktop\mypowershell.ps1
powershell : Invoke-WebRequest : .?? ??? ?????? ???????? ??? ????? ?????
At line:1 char:1
+ powershell -ExecutionPolicy ByPass -File C:\Users\Administrator\Desktop\mypowershell.p ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Invoke-WebReque...??? ????? ?????:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
The site you are trying to access contains content that is prohibited.
If you believe the website you are trying to access does not contain any such
content, please click here.
Above is the error I am getting.

using PsFtp to upload a file to FTP Powershell

I've been wracking my brain on this issue and can't seem to fix it. I'm trying to upload a file to FTP using PSFTP.
The script I'm using:
#------------------------------------------------------
#local variables
$ftp_server = "SERVERNAME"
$ftp_path = "/FTPPATH/PATH"
$local = "C:\ftp\"
$local_in = Join-Path $local "In"
$local_out = Join-Path $local "Out"
$session = "my_ftp_session"
# set up credentials object
$username = "FFandP"
$password = Get-Content "$local_out\Credentials.txt" | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
Set-FTPConnection -Server $ftp_server -Credentials $cred -Session $session -KeepAlive -confirm -UseBinary
Get-ChildItem -Path $local_out |
% {
$ftp_file = "$ftp_path/$($_.Name)" # determine item fullname
Add-FTPItem -Path $ftp_file -LocalPath $_.FullName -Session $session -
}
# -------------------------------------------------
And the error I receive:
Add-FTPItem : Exception calling "GetResponse" with "0" argument(s): "The remote server returned an error: (550) File
unavailable (e.g., file not found, no access)."
At line:22 char:1
+ Add-FTPItem -Path $ftp_file -LocalPath $_.FullName -Session $session
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Add-FTPItem
I've tried running the Add-FTPitem command by itself, but I get the same error.
I can upload to the FTP using FileZilla. I have also tried removing the variables and using hard-coded paths; I get the same error.
Any ideas?
The answer in #Josh's comment solved it for me. Run Add-FTPItem with the -Overwrite parameter.
Add-FTPItem -Path $remotePath -LocaPath $myPath -Overwrite
It took me a moment to figure out this problem, but here is my solution (I had the same problem).
When using Add-FTPItem the -Path parameter must not include the filename itself.
Add-FTPItem
-Path "ftp://SomeServer/SomeDir/"
-LocalPath "C:\SomeFilename.ext"
-Session $session
So in your example it should be:
Add-FTPItem -Path $ftp_path -LocalPath $_.FullName -Session $session
The filename will be added to the remote FTP path. In case you don't want to have the same name you must either rename the file locally first or remotely after.
Change block
Get-ChildItem -Path $local_out | %{ .... }
to one line
Get-ChildItem -Path $local_out | Add-FTPItem -Path $ftp_path