How can I set the permissions of a certificate with Powershell? - powershell

I have some build scripts that generates certificates using CertMgr.exe, however I currently have to manually use the MMC snap-in, navigate to the certificate in question, right click it, select all tasks, select manage private keys, and then set the permissions manually. (For now, I just add Everyone and grant full permissions).
So I run the following script and then goto MMC and look for MACHINE-NAME Root CA and then modify the permission manually. How can I modify my script so I don't have to do this manual step?
param([String]$CertName=$env:COMPUTERNAME)
$CertAuthName= $CertName + " Root CA"
Get-ChildItem cert:\ -DNSNAME $($CertAuthName + "*") -Recurse | Remove-Item
Get-ChildItem cert:\ -DNSNAME $($CertName + "*") -Recurse | Remove-Item
Remove-Item $CertName"*"
Remove-Item $CertAuthName"*"
.\makecert.exe -n $("CN="+$CertAuthName) -r -sv $($CertAuthName+".pvk") $($CertAuthName+".cer") >$null 2>&1
.\makecert.exe -crl -n $("CN="+$CertAuthName) -r -sv $($CertAuthName+".pvk") $($CertAuthName+".crl") >$null 2>&1
.\CertMgr.Exe -add -c $($CertAuthName+".cer") -s -r localMachine root >$null 2>&1
.\CertMgr.Exe -add -crl $($CertAuthName+".crl") -s -r localMachine root >$null 2>&1
.\makecert.exe -sk $CERTNAME -n $("CN="+$CERTNAME) $($CERTNAME+".cer") -iv $($CertAuthName+".pvk") -ic $($CertAuthName+".cer") -sr localmachine -ss my -sky exchange -pe >$null 2>&1

There is an answer on another thread here:
https://stackoverflow.com/a/31175117/85936
that I believe will solve your problem.

Related

Is there any option to extract more than 1 file zip using ExtractToDirectory

I'm trying to create script that will connect to remote server (Windows server 2012 with PS4.0), and extract 5 different files from one directory to another on the remote server.
The script is using psexec.exe to run commands remotely.
psexec \\$server -u <username> -p <password> powershell start Expand-Archive -path "zipfilepath" -destinationpath "destpath"
The expected result is to extract 5 ZIP files inside directory to another directory on remote server.
OK so what you can do is use a Script Block {} and seperate the commands with ;
Powershell -command {Command1;Command2;Command3;etc...}
so something like :
psexec \\$server -u <username> -p <password> powershell -command { Expand-Archive -path "zipfilepath" -destinationpath "destpath"; Expand-Archive -path "zipfilepath" -destinationpath "destpath"; Expand-Archive -path "zipfilepath" -destinationpath "destpath"}

Getting the manifest version of a jar file using unzip in powershell

I am trying to get the implementation version of a jar file using the unzip command in a powershell script. I got few results but not all of them. If i run the same command from the powershell command it works but not from the script.
This is the code that I use
#{n='v';Expression={unzip -q -c $_.fullname META-INF/MANIFEST.MF |findstr Implementation-Version}}
For example a file called rt.jar , I am able to run it directly on the command prompt but it comes empty in the script using the above in the as part of the Get-ChildItem and Select-Object
From the command prompt:
PS C:\PC\Libaudit> unzip -q -c "C:\Program Files\Java\jre1.8.0_201\lib\rt.jar" META-INF/MANIFEST.MF |findstr Implementation-Version
Implementation-Version: 1.8.0_201
Section of the code
ForEach ($Loc in $LocStr){
Get-ChildItem -Path $Loc -Include $Extensions1 -Recurse -ErrorAction SilentlyContinue | Select-Object #{Name='f'; Expression={$_.name}},#{Name="p"; Expression={$_.fullname}},#{Name='h'; Expression={$System}},#{Name='a'; Expression={$values}},#{Name="s";Expression={Get-FileHash $_.fullname -Algorithm "SHA256"}},#{n='v';Expression={unzip -q -c $_.fullname META-INF/MANIFEST.MF |findstr Implementation-Version}},#{Name='Live'; Expression={$live}}
}

How to do a data search on remote pc's

I have a script:
get-childitem c:\users -include *.mov,*.avi,*.asf,*.flv,*.swf,*.mpg,*.mp3,*.mp4,*.wmv,*.wav,*.jpg,*.tif,*.png,*.gif,*.bmp
-recurse > collection.txt
This works great when collecting on a local computer. However, I need to run the same thing on several computers at once. So I tried this in a BAT file:
PSexec #list.txt -u UserID -p Password PowerShell get-childitem c:\users -include *.mov,*.avi,*.asf,*.flv,*.swf,*.mpg,*.mp3,*.mp4,*.wmv,*.wav,*.jpg,*.tif,*.png,*.gif,*.bmp
-recurse > collection.txt 2>&1 pause
This worked on some remote PC's, but I ran into a couple of problems:
1) The collection.txt file contains all the information with no identification of which piece goes with which computer.
2) When running on a single computer, sometimes, it looks like it is running, but never finishes and/or never reports that it has completed or writes to the file.
Is there another way to collect the same data for all users that have logged into the computer? Or, am I just not doing it right
The better approach would be to use PSRemoting rather than PSExec.
$list = "RemoteComputer1","RemoteComputer2"
Invoke-Command -ComputerName $list -ScriptBlock {get-childitem c:\users -include *.mov,*.avi,*.asf,*.flv,*.swf,*.mpg,*.mp3,*.mp4,*.wmv,*.wav,*.jpg,*.tif,*.png,*.gif,*.bmp -recurse} | Out-File .\collection.txt
If you need to use PSExec and a BAT file:
PSexec #list.txt -u UserID -p Password PowerShell -command $env:computername; get-childitem c:\users -include *.mov,*.avi,*.asf,*.flv,*.swf,*.mpg,*.mp3,*.mp4,*.wmv,*.wav,*.jpg,*.tif,*.png,*.gif,*.bmp -recurse 2>&1 > collection.txt

emacs rgrep fails in find command (Windows 7)

This seems like a dumb question and maybe it should be directed to a forum for gnuwin32, but I'll give it a try here.
I'm using grep from within emacs for Windows. I've had to use grep-find vs rgrep, which I would prefer to use because it weeds out many files I don't want to grep. Unfortunately, rgrep seems to create a 'find' command that is so long that it chokes and gives an error.
Using M-x rgrep to search for 'import' in my python files (silly example, I know) gives this output:
find . -type d "(" -path "/SCCS" -o -path "/RCS" -o -path "/CVS" -o -path "/MCVS" -o -path "/.svn" -o -path "/.git" -o -path "/.hg" -o -path "/.bzr" -o -path "*/_MTN" -o -path "*/_darcs" -o -path "/{arch}" ")" -prune -o "(" -name ".#" -o -name ".o" -o -name "~" -o -name ".bin" -o -name ".bak" -o -name ".obj" -o -name ".map" -o -name ".ico" -o -name ".pif" -o -name ".lnk" -o -name ".a" -o -name ".ln" -o -name ".blg" -o -name ".bbl" -o -name ".dll" -o -name ".drv" -o -name ".vxd" -o -name ".386" -o -name ".elc" -o -name ".lof" -o -name ".glo" -o -name ".idx" -o -name ".lot" -o -name ".fmt" -o -name ".tfm" -o -name ".class" -o -name ".fas" -o -name ".lib" -o -name ".mem" -o -name ".x86f" -o -name ".sparcf" -o -name ".dfsl" -o -name ".pfsl" -o -name ".d64fsl" -o -name ".p64fsl" -o -name ".lx64fsl" -o -name ".lx32fsl" -o -name ".dx64fsl" -o -name ".dx32fsl" -o -name ".fx64fsl" -o -name ".fx32fsl" -o -name ".sx64fsl" -o -name ".sx32fsl" -o -name ".wx64fsl" -o -name ".wx32fsl" -o -name ".fasl" -o -name ".ufsl" -o -name ".fsl" -o -name ".dxl" -o -name ".lo" -o -name ".la" -o -name ".gmo" -o -name ".mo" -o -name ".toc" -o -name ".aux" -o -name ".cp" -o -name ".fn" -o -name ".ky" -o -name ".pg" -o -name ".tp" -o -name ".vr" -o -name ".cps" -o -name ".fns" -o -name ".kys" -o -name ".pgs" -o -name ".tps" -o -name ".vrs" -o -name ".pyc" -o -name ".pyo" ")" -prune -o -type f "(" -iname "*.py" ")" -exec grep -i -nH -e "import" {} +
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]
If I cut and paste this command into a cygwin window, which pulls find from /usr/bin, it works just fine and finds several instances. If I paste the same command into a cmd window which then uses gnuwin32/bin/find.exe, I get the same error as above (find: paths must precede expression). I also tried the command in a mingw shell and it works there (using /msys/1.0/bin/find.exe). To complicate matters, copying the mingw version of find into /gnuwin32/bin/ didn't help. No errors, but the grep never actually finds anything. Worse, doing that breaks 'grep-find' in the same way; nothing gets found.
I'm guessing there's a limit to the length of the overall command that I'm hitting here when using the gnuwin32 version of 'find'.
I think I could just give up on gnuwin32 and change my path to point to /msys/1.0/bin for commands that I use, but those commands wouldn't run in a cmd window any longer, at least not without having access to mingw DLLs. Part of me wants to know why the gnuwin32 version of find is choking. Any ideas? Sorry for the long-winded question.
Does emacs know where are the executables?
I have something like this in my .emacs you may want adopt as per your file paths
;;; excutable paths (for unix commands from MSYS and git from msysgit)
(setq exec-path (append exec-path
'("C:/MinGW/msys/1.0/bin/"
"C:/MinGW/bin/"
"c:/MinGW/mingw32/bin"
"C:/Program Files (x86)/Git/bin")))
For me, the correct answer to this problem was found here:
Gnuwin32 find.exe expands wildcard before performing search
I downloaded unxutils.zip listed in the above answer and extracted the find.exe from there to my emacs bin folder. I don't recommend copying to emacs bin folder as a best practice but it avoids a lot of configuration overhead and it gets you up and running instantly.

How to sign all the msi file which are under folder?

I am using signtool to sign my msi.
How to recursively search all the msi in a folder and subfolder then sign them all?
The previous 2 answers show a PowerShell solution.
You can accomplish this easily enough from a CMD.EXE Command Prompt as well.
for /r "yourRootFolder" %F in (*.msi) do signtool sign /a "%F"
Obviously you need to modify your signtool options to suit your needs. The important bit is %F will iteretively hold the name of each .MSI file.
If you want to run the command from within a batch file, then the % must be doubled, so %F becomes %%F in both places.
Here's an example using a code signing certificate (I have only one certificate in $cert):
$cert = Get-ChildItem -Path Cert: -CodeSigningCert -Recurse
Get-ChildItem -Path C:\MsiFolder -Filter *.msi -Recurse | Set-AuthenticodeSignature -Certificate $cert
Assuming you know what command line parameters you need for the MSI signing tool are you can get all MSIs under a given folder like this:
Get-ChildItem -recurse -path C:\MsiFolder -Include *.msi | ForEach-Object {
$msiPath = $_.FullName
$output = & the_msi_sign_tool.exe -msifile $msiPath -parameterB -parameterC 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error $output
}
}
Only one password prompt!
$signExe = 'C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe'
$files = gci 'C:\Temp\*' -Include *.msi | %{('"{0}"' -f $_.FullName)}
$fingerprint = '00000000000000000000000000000000000000000'
$timestampUrl = 'http://rfc3161timestamp.globalsign.com/advanced'
$filesInputArg = $files -join " "
.$signExe sign /tr $timestampUrl /td SHA256 /sha1 $fingerprint $filesInputArg