Open D drive using powershell - powershell

I am editing a powershell script (2.0 I believe) that has the following code to open the cd drive:
$sh = New-Object -ComObject "Shell.Application"
$sh.Namespace(17).Items() |
Where-Object { $_.Type -eq "CD Drive" } |
foreach { $_.InvokeVerb("Eject") }
The problem is that this script now runs on a computer with multiple optical drives so they all open - I only want the D drive to open. I thought changing the script to the following would work:
$sh = New-Object -ComObject "Shell.Application"
$sh.Namespace(17).Items() |
Where-Object { $_.DriveID -eq "D:" } |
foreach { $_.InvokeVerb("Eject") }
but it did not (none of the drives opened). How can I only open the D drive?

The issue you're having is that the result of $sh.Namespace(17).Items() - at least for me - doesn't include a property called DriveID. It does include "Path" though. Try the below.
$sh = New-Object -ComObject "Shell.Application"
$sh.Namespace(17).Items() | ? {$_.Path -eq "D:\"} | % { $_.InvokeVerb("Eject") }

Try filtering on the Path property.
$sh = New-Object -ComObject "Shell.Application"
$sh.Namespace(17).Items() | Where-Object { $_.Path -eq "D:\" } | ForEach-Object { $_.InvokeVerb("Eject") }

I don't see a 'DriveID' property, so the Where-Object is filtering all objects (i.e. nothing is passed to the ForEach). Try using the 'Path' property instead?
$sh = New-Object -ComObject "Shell.Application"
$sh.Namespace(17).Items() |
Where-Object { $_.Path -eq "D:\" } |
foreach { $_.InvokeVerb("Eject") }

Related

Rewriting a Powershell line for another script

There is this existing PS snippet that works as intended:
$creds = New-Object -TypeName System.Management.Automation.PSCredential ("USERID", (new-object System.Security.SecureString));
$FullVM | Where-Object {$_.runtime.powerState -eq "PoweredOn"} |
Select-Object -Property Name,#{N="GuestId";E={$_.Guest.GuestId}},
#{N="Installed Guest OS";E={$_.Guest.GuestFullName}},
#{N="Configured Guest OS";E={$_.Config.GuestFullName}},
#{N="ACCESS";E={$CurrentSession=New-SSHSession -ComputerName $_.Name -AcceptKey -keyfile C:\temp\key.txt -Credential $creds ;(Invoke-SSHCommand -SSHSession $CurrentSession -Command "echo YES" -OutVariable result).output}}
Basically, from what I understand, it collects data and saves them to variables 'or objects?'.
For the last line, it tries to SSH to remote machine(defined in $_.Name) and echoes "YES" if successful and it gets saved to the 'object' "ACCESS":
#{N="ACCESS";E={$CurrentSession=New-SSHSession -ComputerName $_.Name -AcceptKey Credential $creds ;(Invoke-SSHCommand -SSHSession $CurrentSession -Command "echo YES" -OutVariable result).output}}
The issue that I'm running into right now is trying to figure out how to inject/attach/rewrite that same line into this:
foreach ($vmguest in $FullVM) {
$vmguest.Config.Hardware.Device | Where-Object {$vmguest.Guest.GuestFullName -cnotlike "*Microsoft*" -and $_.GetType().Name -match $unwantedHardware} | Foreach-Object {
New-Object -TypeName PSObject -Property #{
Name = $vmguest.name
Label = $_.DeviceInfo.Label
OS = $vmguest.Guest.GuestFullName
}
}
}
How do I rewrite this so it would still provide the same function as from the previous snippet? Do I write it like this?
foreach ($vmguest in $FullVM) {
$vmguest.Config.Hardware.Device | Where-Object {$vmguest.Guest.GuestFullName -cnotlike "*Microsoft*" -and $_.GetType().Name -match $unwantedHardware} | Foreach-Object {
New-Object -TypeName PSObject -Property #{
Name = $vmguest.name
Label = $_.DeviceInfo.Label
OS = $vmguest.Guest.GuestFullName
#{N="ACCESS";E={$CurrentSession=New-SSHSession -ComputerName $_.Name -AcceptKey Credential $creds ;(Invoke-SSHCommand -SSHSession $CurrentSession -Command "echo YES" -OutVariable result).output}}
}
}
}
Could you please guide me on how to accomplish this? Thank you very much in advance!

Use an existing instance of IE unless it contains a specified string

I am using this code to determine whether to use an existing or new instance of IE:
$newInstance = $false
if (Get-Process iexplore -ea silentlycontinue | Where-Object {$_.MainWindowTitle -ne ""}) {
$ie = (New-Object -COM "Shell.Application").Windows() | ? { $_.Name -eq "Internet Explorer" } | Select-Object -First 1
$newInstance = $false
} else {
$ie = New-Object -COM "InternetExplorer.Application"
$newInstance = $true
}
# Elsewhere, I open an array of sites depending on what tabs are already open
foreach ($tab in (New-Object -COM "Shell.Application").Windows() | ? { $_.Name -eq "Internet Explorer" }) {
if ($tab.LocationURL.Contains("~"))
{ $search = $true; break }
}
If a tab is open that has specified text in its title, how can I ignore that instance of IE, and use a second instance to open an array of sites in? I have tried this:
$ie = (New-Object -COM "Shell.Application").Windows() | ? { $_.Name -eq "Internet Explorer" -and $_.LocationName -like ""}
if ($null -ne $ie) {
$ie = (New-Object -COM "Shell.Application").Windows() | ? { $_.Name -eq "Internet Explorer" } | Select-Object -First 1
$newInstance = $false
} else {
$ie = New-Object -COM "InternetExplorer.Application"
$newInstance = $true
}
Not sure if this is what you're looking for?
$searchString = "something"
$ie = (New-Object -COM 'Shell.Application').Windows() | where {$_.Name -eq 'Internet Explorer' -and $_.LocationName -like "*$searchString*"}
if ($null -ne $ie) {
# existing instance found
$newInstance = $false
}
else {
# create new instance
$ie = New-Object -COM 'InternetExplorer.Application'
$newInstance = $true
}
I have got it working; improvements appreciated.
$newInstance = $false
if (Get-Process iexplore -ea silentlycontinue | Where-Object {$_.MainWindowTitle -ne ""}) {
if ((New-Object -COM "Shell.Application").Windows() | ? { $_.Name -eq "Internet Explorer" -and $_.LocationName -notlike "**" }) {
$ie = (New-Object -COM "Shell.Application").Windows() | ? { $_.Name -eq "Internet Explorer" } | Select-Object -First 1
$newInstance = $false
} else {
$ie = New-Object -COM "InternetExplorer.Application"
$newInstance = $true
}
} else {
$ie = New-Object -COM "InternetExplorer.Application"
$newInstance = $true
}

Select IE window using HWND

Wondering if it is possible to select an IE window based on the HWND property (or similar). My script clicks a link which opens a new page in a separate window and I would like to be able to work with this new window.
Here is my code:
$ie.Navigate("https://chaseloanmanager.chase.com/Chaselock/ViewOnlineGuide.aspx") # opens page in new window
while ($ie.Busy -eq $true){Start-Sleep -Seconds 2}
$childWindow = Get-Process | Where-Object {($_.ProcessName -eq 'iexplore')} | Get-ChildWindow | Where-Object {$_.ChildTitle -match 'Lending'}
$childWindow.MainWindowHandle # gets HWND of new window
$shell = New-Object -ComObject Shell.Application
$ie3 = $shell.Windows() | Where-Object {$_.HWND -match $childWindow.MainWindowHandle} # does not find window
You can get the IE comobject by searching through Windows() in Shell.Application.
$shell = New-Object -ComObject Shell.Application
$ie = $shell.Windows() | Where-Object { $_.LocationURL -match 'Lending' }
#$ie = $shell.Windows() | Where-Object { $_.HWND -eq 2951084 }
$ie.Navigate("http://www.stackoverflow.com")

Powershell, URL shortcut

I've got a problem and i need your help. I'm trying to do a shortcut from the active URL. I tried a few things and got to this.
Param([switch]$Full, [switch]$Location, [switch]$Content)
$urls = (New-Object -ComObject Shell.Application).Windows() |
Where-Object {$_.LocationUrl -match "(^https?://.+)|(^ftp://)"} |
Where-Object {$_.LocationUrl}
if($Full)
{
$urls
}
elseif($Location)
{
$urls | select Location*
}
elseif($Content)
{
$urls | ForEach-Object {
$ie.LocationName;
$ie.LocationUrl;
$_.Document.body.innerText
}
}
else
{
$urls | ForEach-Object {$_.LocationUrl}
}
$Shortcut = $WshShell.CreateShortcut("E:\Powershell\Ziel\short.lnk")
$Shortcut.TargetPath = "$urls"
$Shortcut.Save()
But i get an shortcut which makes no sense. What do i do wrong? I'm happy about any suggestion.
I tried now doing it like this:
Param([switch]$Full, [switch]$Location, [switch]$Content)
$urls = (New-Object -ComObject Shell.Application).Windows() |
Where-Object {$_.LocationUrl -match "(^https?://.+)|(^ftp://)"} |
Where-Object {$_.LocationUrl}
if($Full)
{
$urls
}
elseif($Location)
{
$urls | select Location*
}
elseif($Content)
{
$urls | ForEach-Object {
$ie.LocationName;
$ie.LocationUrl;
$_.Document.body.innerText
}
}
else
{
$urls | ForEach-Object {$_.LocationUrl}
}
$url = $urls | ForEach-Object {$_.LocationUrl} | select -First 1
$Shortcut = $WshShell.CreateShortcut("E:\Powershell\Ziel\short.lnk")
$Shortcut.TargetPath = $url
$Shortcut.Save()
But no it tells me that "$Shortcut = $WshShell.CreateShortcut("E:\Powershell\Ziel\short.lnk")" has the value NULL. I mean, how is that even possible. I don't get it. Please help.
This one is wrong... (this is not a valid url, it just an array of objects)
$Shortcut.TargetPath = "$urls"
You need to select one of the url's first, for example:
$url = $urls | ForEach-Object {$_.LocationUrl} | select -First 1
Then:
$Shortcut = $WshShell.CreateShortcut("E:\Powershell\Ziel\short.lnk")
$Shortcut.TargetPath = $url
$Shortcut.Save()
if you want to create a url for each of the URL's Array, then you can use
foreach, like this:
foreach ($url in $URLs)
{
$UrlName = $url.LocationName.Substring(0,8)
$Link = $url.LocationUrl
$Shortcut = $WshShell.CreateShortcut("E:\Powershell\Ziel\$UrlName.lnk")
$Shortcut.TargetPath = $Link
$Shortcut.Save()
}

Shell.Application - write new Values?

I have a directory with MP3 files. I can read the properties with this script. How I can write properties (Album, Genre, etc.)?
$com = (New-Object -ComObject Shell.Application).NameSpace('C:\Users\Peter\Music')
for( $index = 0; ((-not $bitrateAttribute) -or (-not $albumAttribute)); ++$index ) {
$name = $com.GetDetailsOf($com.Items,$index)
if ($name -eq 'Album') {$albumAttribute = $index}
if ($name -eq 'Bit rate') {$bitrateAttribute = $index}
}
$com.Items() | ForEach-Object {
New-Object -TypeName PSCustomObject -Property #{
Name = $_.Name
Album = $com.GetDetailsOf($_,$albumAttribute)
BitRate = $com.GetDetailsOf($_,$bitrateAttribute)
} | Select-Object -Property Name,Album,BitRate
}
Or is there a better way to write ID3 tags to MP3 files?