Extracting .exe file using powershell - powershell

I am trying to extract .exe file using powershell without any other tools.
I tried to use System.IO.Compression.ZipFile, but that works only for .zip files..
$zip_file = Get-Item ("C:\Users\00WORK\gs\gs.exe")
$destination = Get-Item ("C:\Users\tuna")
[System.IO.Compression.ZipFile]::ExtractToDirectory($zip_file,$destination)
Also tried this, but without any success
start-process C:\Users\Downloads\gs.exe -Argumentlist "/a"
Tried also this but once again without any succes
$shell = new-object -com shell.application
$zip = $shell.NameSpace(“C:\Users\00WORK\gs\gs.exe”)
foreach($item in $zip.items())
{
$shell.Namespace(“C:\Users\tuna”).copyhere($item)
}
Thanks for help.

If you have tried
start-process C:\Setup.exe -Argumentlist "/a"
Then it is not possible using powershell, this command is completely dependant on how the file was packaged, if all else fails I personally would use a utility like 7-Zip, but as you said you would not like to use utilities.

I had this same problem recently as well. Dewi's answer would not have worked for me. I solved it like this:
mv gs.exe gs.zip
Expand-Archive -Path gs.zip
Optionally, you can rename it back when you're done, if you need the exe for other purposes.
mv gs.zip gs.exe
Note that you'll need PowerShell 5 or newer to use Expand-Archive. Thankfully, this is available as a download all the way back to Win 7 as Microsoft KB3191566.

Yeah well powershell doesn't recognize all compression algorithms. I am trying to do this with an HP driver pack file which comes in a self extracting .exe file. Even if you change the filename to a .zip it will not extract the files and instead throws a New-Object exception error.

Related

Using powershell script to unzip a folder.

I am having some problems with my powershell script to unzip a zipped folder. Any one have any solutions? I have searched the net but everyone seem to be using powershell v1.0 and above.
Does anyone have a solution to unzip a zipped folder for powershell 1.0?
Thanks in advance!
I don't have a Powershell 1 to test with (who does these days!) but I found this snippet on my machine from the days before Expand-Archive was available:
# Unzip stuff
$shell = new-object -com shell.application
$zip_file = get-item "C:\temp\c1.zip"
$Location = $shell.namespace("C:\temp")
$zipFolder = $shell.namespace($zip_file.fullname)
$Location.Copyhere($zipFolder.items())
It will unzip the file to the folder it is in. I believe it should work with PS1, but you'll have to test it yourself.

Adding .inf drivers using PowerShell, possible?

Are we able to install drivers via their .inf files etc. using a PowerShell cmdlet? When Googling I found, Add-WindowsDriver but I think this one is for an offline Windows image. Does that mean an image that is not currently used on an OS? If not, please teach me how to write the parameters. Thank you!
This PowerShell script will do what you want:
Get-ChildItem "C:\Driver File Location" -Recurse -Filter "*inf" | ForEach-Object { PNPUtil.exe /add-driver $_.FullName /install }
You don't need Powershell or advanced CMD programming, because pnputil.exe has a /subdirs command line switch and can slurp multiple .inf files at once. On my system (Windows 10 x64 21H2), you can simply execute:
pnputil /add-driver *.inf /install /subdirs
That does what I would expect.
pnputil.exe's help tells everything we need. Just execute pnputil without further parameters, and it outputs an understandable help screen (that is too long to post it here).
It can be done using the Install-DeviceDriver cmdlet from the DeviceManagement module. See my answer here for an example.

working with relative paths in powershell WebClient and FileStream

I'm tasked with writing a powershell script to perform a file download, which will eventually be executed as a scheduled task once a week. I have no background in programming in the windows environment so this has been an interesting day.
I am experiencing a problem with the unexpected handling of the $pwd and $home of the shell.
I pass into my program a download URL and a destination file. I would like the destination file to be a relative path, e.g., download/temp.txt.gz
param($srcUrl, $destFile)
$client = new-object System.Net.WebClient
$client.DownloadFile($srcUrl, $destFile)
Ungzip-File $destFile
Remove-Item $destFile
This actually fails on the call to Remove-Item. If $destFile is a relative path then the script happily downloads the file and puts it in a file relative to $home. Likewise, I then unzip this and my function Ungzip-File makes use of System.IO.Filestream, and it seems to find this file. Then Remove-Item complains that there is no file in the path relative to $pwd.
I am a bit baffled, as these are all part of the shell, so to speak. I'm not clear why these functions would handle the path differently and, more to the point, I'm not sure how to fix this so both relative and absolute paths work. I've tried looking at the io.path methods but since my $home and $pwd are on different drives, I can't even use the IsPathRooted which was seemed so close when I found it.
Any help?
You have to be aware of where you are in the path. $pwd works just fine on the command shell but let's say you have started your script from a scheduled job. You might think $pwd is where your script resides and code accordingly but find out that it actually uses, say %windir%\system32.
In general, I would use fullpath to destination and for paths relative to script folder I would use $PSScriptRoot/folder_name/file_path.
There are catches there too. For example, I noticed $PSScriptRoot will resolve just fine within the script but not within Param() block. I would highly suggest using write-verbose when coding and testing, so you know what it thinks the path is.
[CMDLETBINDING()] ## you need this!
Param()
write-verbose "path is $pwd"
Write-Verbose "removing $destFile"
Remove-Item $destfile
and add -verbose when you are calling your script/function:
myscript.ps1 -verbose
mydownloadfunction -verbose
To use a relative path, you need to specify the current directory with ./
Example: ./download/temp.txt.gz
You can also change your location in the middle of the script with Set-Location (alias: cd)

Powershell Get-ChildItem doesn't work properly on IIS directory

I was going to write up a simple alias 'iis' to invoke the IIS Manager, which is 'C:\Windows\System32\inetsrv\InetMgr.exe'
set-alias iis "OpenIIS.ps1"
and in the OpenIIS.ps1 I have
$item = "C:\Windows\system32\inetsrv\InetMgr.exe"
invoke-item -path $item
This doesn't work. The error I get is "The system cannot find the file specified"
In fact, just doing a Get-ChildItem on the inetsrv won't show the InetMgr.exe (no difference with -Force switch)
Get-ChildItem C:\Windows\system32\inetsrv\*.exe -force
Obviously I can see it in Explorer and I can launch it using cmd, but not with Powershell it seems. Also, Powershell is running as Administrator.
What is going on?
As a workaround I tried creating a link to the file and then invoking that link from Powershell. I now get a 'NotSpecified' Win32Exception.
I have originally used 64 bit Powershell, but get the same result on the x86 Powershell (both run as Administrator)
Are you at the elevated PowerShell prompt? Some system files may not show up unless you use -Force parameter with Get-ChildItem.
I think evidently the file InetMgr.exe is not there as when I do a get-childitem in the mentioned directory,it lists the "InetMgr.exe" there.
This may not be the problem with Get-ChildItem or the Alias you created but instead with ur IIS Server.

Why don't .NET objects in PowerShell use the current directory?

When you use a .NET object from PowerShell, and it takes a filename, it always seems to be relative to C:\Windows\System32.
For example:
[IO.File]::WriteAllText('hello.txt', 'Hello World')
...will write C:\Windows\System32\hello.txt, rather than C:\Current\Directory\hello.txt
Why does PowerShell do this? Can this behaviour be changed? If it can't be changed, how do I work around it?
I've tried Resolve-Path, but that only works with files that already exist, and it's far too verbose to be doing all the time.
You can change .net working dir to powershell working dir: [Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
After this line all .net methods like [io.path]::GetFullPath and [IO.File]::WriteAllText will work without problems
The reasons PowerShell doesn't keep the .NET notion of current working directory in sync with PowerShell's notion of the working dir are:
PowerShell working dirs can be in a provider that isn't even file system
based e.g. HKLM:\Software
A single PowerShell process can have
multiple runspaces. Each runspace can be cd`d into a different file
system location. However the .NET/process "working directory" is
essentially a global for the process and wouldn't work for a
scenario where there can be multiple working dirs (one per runspace).
For convenience, I added the following to my prompt function, so that it runs whenever a command finishes:
# Make .NET's current directory follow PowerShell's
# current directory, if possible.
if ($PWD.Provider.Name -eq 'FileSystem') {
[System.IO.Directory]::SetCurrentDirectory($PWD)
}
This is not necessarily a great idea, because it means that some scripts (that assume that the Win32 working directory tracks the PowerShell working directory) will work on my machine, but not necessarily on others.
When you use filenames in .Net methods, the best practice is to use fully-qualified path names. Or use
$pwd\foo.cer
If you do in powershell console from:
C:\> [Environment]::CurrentDirectory
C:\WINDOWS\system32\WindowsPowerShell\v1.0
you can see what folder .net use.
That's probably because PowerShell is running in System32. When you cd to a directory in PowerShell, it doesn't actually change the working directory of powershell.exe.
See:
PowerTip article on syncing the two directories
Channel9 forum thread
I ran into the same problem a long time ago and now I add the following to the beginning of my profile:
# Setup user environment when running session under alternate credentials and
# logged in as a normal user.
if ((Get-PSProvider FileSystem).Home -eq "")
{
Set-Variable HOME $env:USERPROFILE -Force
$env:HOMEDRIVE = Split-Path $HOME -Qualifier
$env:HOMEPATH = Split-Path $HOME -NoQualifier
(Get-PSProvider FileSystem).Home = $HOME
Set-Location $HOME
}