So I have a working Windows.Forms.FolderBrowserDialog function for Folder selection in my Script.
I noticed Today that I can't any external Shares or even see them with it.
Is there another function for that or is there some special attribute I have to set to see external Shares?
How do you mean "external"? It will see mapped drives and anything in the "Network" folder, though bear in mind that local network discovery could be disabled in the OS and you'd have to enable this in Windows
If you run this with a UNC folder path it should open the browser in that folder:
$RootFolder = '\\myserver\myfoldername'
$FolderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
$FolderBrowser.Description = 'Select a folder'
$FolderBrowser.ShowNewFolderButton = $false
$FolderBrowser.SelectedPath = $RootFolder
$result = $FolderBrowser.ShowDialog((New-Object System.Windows.Forms.Form -Property #{TopMost = $true }))
Related
I am trying to use PowerShell to Sync Payroll files stored on SFTP to SharePoint. I have most of the code written, the only thing I can't figure out is if there is a way to avoid temporarily downloading the file to the disk. Given the sensitivity of these files I would rather store the files as a variable not unlike how get-content works so no one on the Jenkins slave would be able to see its content or undelete temp files.
Here is my working code that does download the file:
$session = New-Object WinSCP.Session
$session.Open($sessionOptions)
$file = $session.ListDirectory("/") | select -ExpandProperty files | ? {$_.FileType -ne "D"} | select -First 1
$session.GetFiles($file, "c:\temp\$($file.name)", $False, $transferOptions)
$session.Close()
Is there something I can use in replacement of the second parameter of WinSCP.Session.GetFiles [C:\temp\$($file.name)] that would allow me to drop the file directly into memory so I can turn around and dump the to SharePoint?
If you were wondering how I would then get it into sharepoint I have used this with get-content without issue:
$fileToUpload = get-content c:\temp\test.csv -Encoding Byte
$FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.Content = $fileToUpload
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.Url = "test.csv"
$Upload = $Folder.Files.Add($FileCreationInfo)
$Ctx.Load($Upload)
$Ctx.ExecuteQuery()
WinSCP simply doesn't do it. I had been hoping for a downstream object to take the replcement of a file path but that does not seem to be possible. However I did figure this out. Moving to the posh-ssh module I was able to use the Get-SFTPContent command which allows me to read in the file to memory.
install-module posh-ssh
import-module posh-ssh
$Session = New-SFTPSession -ComputerName $SFTPHostName -Credential $SFTPcredential
Get-SFTPContent -SessionId $session.SessionId -Path $file.FullName -Encoding unicode -ContentType byte
Streaming a context of a remote file is supported since WinSCP 5.18 beta using the Session.GetFile method.
$stream = $session.GetFile($file)
I have to mass-change shortcuts (.lnk) with PowerShell in an enterprise environment.
Users maybe have wrong shortcuts on their desktop. The desktop folder is located on our central storage. I need to correct them, if the shortcuts have wrong arguments. I am talking about 5.000 users.
My code is ready and working fine. It is based on some examples I found on Google.
In some examples I did see something like:
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ShortcutObject)
I don't know what this is for?
Broken down the relevant part of my code looks like this:
$UserShortcuts = Get-ChildItem -Path "MyFolder" -ChildPath "SmithJ\Desktop") -Filter *.lnk |
Where-Object Name -Match "MyShortcut"
foreach ($UserShortcut in $UserShortcuts) {
$sh = New-Object -ComObject WScript.Shell
$ShortcutObject = $sh.CreateShortcut($($UserShortcut.FullName))
$ShortcutObject.Arguments
# ...
}
What about the ReleaseComObject()?
Do I have to do this after every object?
It is working without. Do I have to use it?
EDIT:
With the information of Bill_Stewart I think it would be correct like this:
$UserShortcuts = Get-ChildItem -Path "MyFolder" -ChildPath "SmithJ\Desktop") -Filter *.lnk |
Where-Object Name -Match "MyShortcut"
$sh = New-Object -ComObject WScript.Shell
foreach ($UserShortcut in $UserShortcuts) {
$ShortcutObject = $sh.CreateShortcut($($UserShortcut.FullName))
$ShortcutObject.Arguments
# ...
}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($sh)
According to the documentation:
Therefore, use the [sic] ReleaseComObject only if it is absolutely required.
Implicit in this sentence is that you have an understanding of the technical details of how managed code (in this case, PowerShell, which uses .NET) uses COM objects.
For PowerShell scripts calling scripting runtime COM objects (such as WshShell, WshShortcut, WshUrlShortcut, etc.), there is no need to use ReleaseComObject as the .NET runtime (CLR) will automatically release them when they are no longer in use.
This is not necessarily the case with all COM objects when automated from PowerShell, but for scripting runtime objects releasing is unnecessary.
I'm writing my first powershell script and I'm having a little trouble.
Up to this point my system creates a directory tree and populates it with files. The final step is to put a shortcut on my desktop.
I've come up with the code below:
$ShortcutFile = "$home\Desktop\" + $protocol + ".lnk"
If ( (test-path -path "$ShortcutFile") -ne $true)
{
$WScriptShell = New-Object -ComObject WScript.Shell
$Shortcut = $WScriptShell.CreateShortcut($ShortcutFile)
$Shortcut.TargetPath = $root_path
$Shortcut.Save()
}
This doesn't work as I'm sure any experienced powershell user knows. A file is created rather than a directory. I imagine the correct way to fix this is to change one of the object members in WScript.Shell which control's the file type. I have had no luck locating any resources on how to do this specifically, or any other way to go about doing it. I found the API on the MSDN website but there where only a few members listed. There must be more.
What is the best way to accomplish this?
Thanks
New-Item -itemtype symboliclink -Path "PathWhereYouWantToPutShortcut" -name "NameOfShortcut" -value "PathOfWhatYourTryingToLinkTo"
New-Item Documentation
Assuming that you mean the shortcut type is a File rather than a File folder then a workaround is to make an Application launcher instead, which always works.
I originally found this solution here.
$wsshell = New-Object -ComObject WScript.Shell
$lnk = $wsshell.CreateShortcut($ShortcutFile)
$lnk.WindowStyle = 1
$lnk.TargetPath = "explorer.exe"
$lnk.Arguments = $TargetPath
$lnk.IconLocation = "explorer.exe,0"
$lnk.save() # This will overwrite the previous link if it existed
I experienced this when creating a shortcut to a directory that didn't exist. If I simply created the directory ahead of time, then the shortcut worked correctly.
Create file, lets say at C:\randomname\file.txt,
Now run the following script via PowerShell:
$shell = new-object -com shell.application
$folder = $shell.NameSpace("C:\randomname")
$folder.Items() | where {$_.Name -eq "file.txt"}
Observe no output is produced which is rather unexpected.
Any idea how to resolve this situation in a reasonable manner other than modifying Windows settings?
EDIT:
To prevent confusion, this is just a stripped down version of my actual problem. Reason why I am using shell.application and not Get-ChildItem is that my randomname folder is actually zipped, i.e. I have randomname.zip and my actual code looks like this:
$shell = new-object -com shell.application
$zip = $shell.NameSpace("C:\randomname.zip")
$folder = $zip.Items() | where {$_.Name -eq "randomname"}
$folder.GetFolder.Items() | where {$_.Name -eq "file.txt"}
FolderItem.Name return value depends on the value of particular Windows setting. Try the following:
Open Control Panel,
Folder Options, View tab,
Uncheck Hide extensions for known file types.
Re-run the script and you will see the expected output:
Application : System.__ComObject
Parent : System.__ComObject
Name : file.txt
Path : C:\randomname\file.txt
...
I was trying to write a portable script but after finding out how Name works this seems rather hard as I have no control over Windows settings of our customers and there is nothing like FullName for FolderItem so I can't figure out the reliable way out.
EDIT:
Based on suggestion from Nick Sedgewick, that .Path always returns filename with extension, unlike .Name, I was able to create a working workaround which does not depend on Windows settings and looks like this:
$shell = new-object -com shell.application
$folder = $shell.NameSpace("C:\")
$folder.Items() | where {(split-path $_.Path -leaf) -eq "file.txt"}
A Namespace Item has a PATH property, which returns full path and filename for files, and always includes the filename extension, whether the user has 'hide filename extensions' set or not.
So, use 'Path' instead of 'Name' and either write a function to pass $_.Path to which can the extract the filename part, or use an equivalent of the LIKE operator if there is one in powershell
Little new to powershell. I am trying to locate a get-childitem like command that will work on an ftp site.
Here is some psuedo-code:
$target = "c:\file.txt"
$username = "username"
$password = "password"
$ftp = "ftp://$username:$password#myftpsite"
$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)
#below is the code that does not work, get-childitem needs a local path
$name = get-childitem -path $ftp
The get-childitem only works with a local path. Does anyone know how I could access the filenames in this manner when on an ftp site?
Thanks
What you would need is a PowerShell provider for FTP if you wanted Get-ChildItem to work on a remote filesystem accessed by FTP. This forum post mentions work being done by Nick Howell on an FTP provider. Other than that, I haven't heard of any other FTP providers for PowerShell.