I need a way to read file metadata using Powershell Core 7.x on macOS.
In a MS Windows environment, I was able to use Shell.Application COM object and getDetailsOf() method to retrieve the information. However, I can't find this option in PowerShell Core on macOS.
I found someone who used external commands (I guess some are written in python) in PowerShell core to retrieve the information, but I would like to do that using PowerShell only.
Does anyone know if this is possible with Powershell core?
Thanks
Instead of using a "Shell.Application COM object" to execute an external tool, you can just use the Start-Process cmdlet and capture the output of this process:
$f = New-TemporaryFile
Start-Process exiftool -ArgumentList "myImage.jpg" -RedirectStandardOutput $f.FullName -Wait
$result = Get-Content -Path $f.FullName
Remove-Item -Path $f.FullName
# Now, the result of the exiftool is available in $result for further processing
Shell.Application is part of Win32, it's literally the Windows shell!
So when you load it via COM, you're basically telling Powershell do the same function the shell uses for the UI details tab, GetDetailsof. COM is just how you're communicating to the process, to tell it to run a particular method.
So could this work on Powershell Core? Only if you're running Powershell Core on a Windows system. That is because the dependency is a method provided by the platform. You have no other choice than to read the metadata yourself, via another library.
You might want to check out, metadata-extractor-dotnet
Something like that is what you'd need to implement the functionality. I don't have experiance using that lib myself, but at least it might provide a good jump off point for further research.
Related
I'm building an installer using advanced installer and have run into a problem trying to add dates into the log file. I tried a command using cmd which worked, however when I added it to the MSI commandline all the date values came out as blank. Below is the parameters I pass for the MSI
/L*V "C:\Log_%date:~4,2%.%date:~7,2%.%date:~10,4%-%time:~0,2%.%time:~3,2%.%time:~6,2%.log"
We are trying to make the log be Log_04.05.2019-15.03.45.log instead of Log.log since the logs get overwritten when uninstall happens or on a retry of an installation..
Advanced Installer: Sorry, I see that I must have misunderstood. You are trying to set the log file name from within Advanced
Installer. Will have a quick look. Where do you specify this command line in the tool? Please note that setting the logging policy for "Global Logging" will ensure unique log file names and that every MSI operation is logged in TMP.
Clarification: So it looks like you don't want to write to the log, but to control the file name of the log file itself?
PowerShell: I find batch files clunky with regards to stuff like this. Can you invoke the installation via Powershell? I don't really use PowerShell, but seeing as it can use .NET, maybe a simple conversion of this C# call would do the trick?
You want something like: "Log_04.05.2019-15.03.45.log", so you could perhaps try this in C#:
Console.WriteLine("Log_" + DateTime.Now.ToString("dd.MM.yyyy-HH.mm.ss") + ".log");
Here is a blog on using PowerShell with Windows Installer, see towards the bottom for this PowerShell snippet (again, I do not use PowerShell for this purpose):
$DataStamp = get-date -Format yyyyMMddTHHmmss
$logFile = '{0}-{1}.log' -f $file.fullname,$DataStamp
$MSIArguments = #(
"/i"
('"{0}"' -f $file.fullname)
"/qn"
"/norestart"
"/L*v"
$logFile
)
Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow
Maybe also have a read about the Windows Installer PowerShell
Module (Heath Stewart) as linked to in this general purpose
answer:
How can I use powershell to run through an installer?.
Special-purpose PowerShell Module making Windows Installer operations
less clunky.
Some Links:
Various MSI logging methods: Enable installation logs for MSI installer without any command line arguments
Windows Installer Logging
I am writing a Powershell script to make a raw copy of a drive and I have been unable to find a way to complete this.
On Linux, I would use 'dd' to perform this copy.
There are a handful of tools that can do this on Windows but none that I can control directly from the command line. (All have GUI interfaces)
Is there a method to make a physical copy of a drive through Powershell?
Thanks.
I've been trying to do this for a while myself and I finally found a good answer.
Git for windows ships with the whole set of GNU core utilities (updated vs what you can find separately) including dd!
Just install Git for Windows or extract the portable version, from there inside of the install directory in git\usr\bin\ you will find the binaries for all of the GNU utils including dd (tested working)
Some further notes on usage in windows since \dev\sda\ isn't a thing:
$DiskDrives = Gwmi Win32_diskdrive | select DeviceID,BytesPerSector,Index,Caption,InterfaceType,Size,TotalSectors,SerialNumber | Out-GridView -OutputMode Multiple -Title 'Select Source Drive(s)'
$BaseOutputPath = 'D:\'
$DiskDrives | %{
. ('C:\Program Files\Git\usr\bin\dd.exe if={0} of={1} bs={2}' -f $_.DeviceID,(-join($BaseOutputPath,(-
join($Env:ComputerName,$_.Index)),'.img')),$_.BytesPerSector)
}
The included filename logic is just a placeholder, you can replace that parenthetical with a call to Read-Host if you want it to prompt you for the filename/path.
It is a bit annoying but you really do have to use WMI as the values returned by Get-Disk don't seem to work.
You might already know that cygwin on Windows supports some Linux commands including dd. I have used it on several occasions to copy disks and load ISOs to USB and it works perfectly.
Windows 10 comes with linux now. Windows Subsystem for Linux. You can enable it as a feature. You can even get WSL 2 with the real kernel in 1903 & 1909: https://devblogs.microsoft.com/commandline/whats-new-in-the-windows-subsystem-for-linux-september-2020/
Get-CimInstance -ClassName Win32_DiskDrive | Format-List -Property DeviceID,BytesPerSector,Index,Caption,InterfaceType,Size,TotalSectors,SerialNumber
Following up #Chirishman answer, for Powershell 7.2, The Gwmi may missing from the powershell.
The alternative command to get the DeviceId and other info is available as above.
Then you can use dd if={DeviceId} of=<target_file>.
I am busy with creating a PowerShell script where a folder needs to be copied to another folder as a part of the script.
For this I would like to use the standard Windows copy interface and leverage from the prompts and selections like “There is already a file with the same name in this location.”, “Do you want to merge this folder”, “Do this for all”, etc. instead of programming this all myself.
I investigated a view directions:
Using the IFileOperation::CopyItem method as e.g. HowTo: Display progress dialog using IFileOperation but I could find any hint of how to embed this in PowerShell
Using Verbs() Copy/Paste but although the example Invoke-FileSystemVerb -Path "C:\TestDir -Verb Cut; Invoke-FileSystemVerb -Path "\\server\share" -Verb Paste” suggests otherwise, I can paste files that are manually copied/cut but could not copy/cut files with using the CmdLet or simply using the Verb.DoIt() method (I suspect this for a security reason).
Simulate a drag-drop?
But could not find any working solution.
Any suggestion how to do this from PowerShell?
I use this to extract from ZIP files which seems to come up with all the prompts and progress bar:
$shell = New-Object -Com Shell.Application
$folder = $shell.NameSpace(“$path\Folder”)
$shell.NameSpace($otherpath).CopyHere($folder)
There is script command on GNU/Linux machine which allows to capture all command line activity into a file . This is really helpful tool especially when we learn something new and we want to save the commands and their output for future reference.
I am currently learning the Git on Windows PowerShell terminal and I wanted to capture all the commands and their output in a file for future reference.
Is there any way/command do achieve it on Windows PowerShell?
Try with Start-Transcript and Stop-Transcript cmdlet.
You can also use Start-Transcript for ISE Editor module because these CmdLet don't work natively in ISE.
It exists standard CmdLets : Start-Transcript and Stop-Transcript.
You'll find more informations about these CmdLet in the associeted TechNet documentation.
What is the powershell equivalent of 'less'?
I see 'more', but it lacks some of the features I rely on (e.g. searching through the file)
I seek a pager (equivalent of 'less') which allows searching (match or ignore case), multiple files at once, etc.
Some of our servers run windows 2008 and I lack admin privileges to install cygwin
I had heard windows 2008, MSFT got their act together and provided some easy-for-admins tools.
Update:
I should give some context:
I know little about power shell
New servers have 2008 on them
While I affection for many tools of yore, the dos prompt is not one of them
I was hoping that Powershell had the equivalent of grep,ls,less, xargs, et
I understood that powershell gave us those tools
I fired off my question quickly.
thanks
It reads like you know you can do this:
gc logfile.log | more
(GC is an alias for Get-Content).
You may be able to do the filtering etc.. with this more information can be found by running these commands:
Get-Help Get-Content Get-Help
Get-Content -Examples
(Get-Help gc would work fine as well).
And the bits you may be interested in are limit\filter etc...
Get-Help gc -Parameter * | more
I just use the GOW version of less, works fine.
I don't know of any direct analogue for less in powershell that you can implement easily. Your best bet is to get a windows implementation of less that is outside of cygwin, that way you can just drop in the binary somewhere accessible to your account.
to get grep/vim/wget and other Linux like commands in powershell I suggest running.
iex (new-object net.webclient).downloadstring(‘https://get.scoop.sh’)
then
scoop install grep
scoop install perl
scoop install vim
and to get a list of all of them
scoop search
In Windows 10 PowerShell + Cygwin I use:
gc .\myfile.log | less
Previously I was trying to use cygwin directly:
less .\myfile.log
but it shows binary file because of invalid charset setting between 32b-bit and 64-bit.
I was hoping that Powershell had the equivalent of grep,ls,less, xargs, et
In the case you missed this question (top voted) you might enjoy this answer.