Create multiple shortcuts to subfolders with the same name - powershell

Beginner Here, i PUt together this but cant make it work..
I have multiple folders each of them contain own subfolder ‘zero’ , I’m trying to create shortcuts to each of those subfolders with the name of its parent folder
...
$app = New-Object -ComObject "WScript.Shell"
$container = "C:\Users\$app = New-Object -ComObject "WScript.Shell"
$container = "C:\Users\Desktop\skty"
$path = "C:\Users\Desktop\fold"
if (!(Test-Path $container)) {
New-Item -Type Directory -Path $container | Out-Null
}
Get-Childitem -Path $path -Recurse -Include "zero*" | Foreach-Object {
{ $ShortcutFile = "$container\$_.Directory.Parent.Name + $_.Name"
$app.CreateShortcut($ShortcutFile)
$Shortcut.TargetPath = $_.FullName
$Shortcut.Save()
}
...

This should help you get started:
This will put a shortcuts on everones Desktop pointing to the users Documents folder.
$container = Get-ChildItem -Path C:\Users
ForEach ($upath in $container){
$sfilepath = $upath.FullName + "\Documents"
$scutpath = $upath.FullName + "\Desktop"
$SourceFilePath = $sfilepath
$ShortcutPath = "$scutpath" + "\Documents.lnk"
$WScriptObj = New-Object -ComObject ("WScript.Shell")
$shortcut = $WscriptObj.CreateShortcut($ShortcutPath)
$shortcut.TargetPath = $SourceFilePath
$shortcut.Save()
}
If you know the location you need to use, you can use Get-Content
Please play with the location to get the output you need.

Related

Can someone help me to fix this Powershell script ? i'm new to this and somehow its not working

These are 3 codes, first one to make a directory and second one to save the .ico file in that directory.
The last code is to make a shortcut with the .ico file as icon.
I think i did something wrong with the order of the script.
$path = "C:\Program Files\icons"
If(!(test-path $path))
{
New-Item -ItemType Directory -Force -Path $path
}
$Base64String = '#base64string'
$Image = "C:\Program Files\icons\Alphen.ico"
[byte[]]$Bytes = [convert]::FromBase64String($Base64String)
[System.IO.File]::WriteAllBytes($Image,$Bytes)
param (
[system.string]$ShortcutName = "portaal",
[system.string]$ShortcutUrl = "https://portal.rotterdam.nl",
[system.string]$IconURL = "C:\Program Files\icons\Alphen.ico",
[system.string]$Desktop = [Environment]::GetFolderPath("Desktop"),
[system.string]$IntuneProgramDir = "$env:APPDATA\Intune",
[System.String]$TempIcon = "$IntuneProgramDir\msedge.exe",
[bool]$ShortcutOnDesktop = $True,
[bool]$ShortcutInStartMenu = $True
)
#Test if icon is currently present, if so delete it so we can update it
$IconPresent = Get-ChildItem -Path $Desktop | Where-Object {$_.Name -eq "$ShortcutName.lnk"}
If ($null -ne $IconPresent)
{
Remove-Item $IconPresent.VersionInfo.FileName -Force -Confirm:$False
}
$WScriptShell = New-Object -ComObject WScript.Shell
If ((Test-Path -Path $IntuneProgramDir) -eq $False)
{
New-Item -ItemType Directory $IntuneProgramDir -Force -Confirm:$False
}
#Start download of the icon
Start-BitsTransfer -Source $IconURL -Destination $TempIcon
if ($ShortcutOnDesktop)
{
$Shortcut = $WScriptShell.CreateShortcut("$Desktop\$ShortcutName.lnk")
$Shortcut.TargetPath = $ShortcutUrl
$Shortcut.IconLocation = $TempIcon
$Shortcut.Save()
}
if ($ShortCutInStartMenu)
{
$Shortcut = $WScriptShell.CreateShortcut("$env:APPDATA\Microsoft\Windows\Start Menu\Programs\$ShortcutName.lnk")
$Shortcut.TargetPath = $ShortcutUrl
$Shortcut.IconLocation = $TempIcon
$Shortcut.Save()
}
Your code is fine. The param must be in the beginning. I have changed the order.
Recommendation is to put the entire thing in try/catch block so that you can catch the exceptions and error messages.
param (
[system.string]$ShortcutName = "portaal",
[system.string]$ShortcutUrl = "https://portal.rotterdam.nl",
[system.string]$IconURL = "C:\Program Files\icons\Alphen.ico",
[system.string]$Desktop = [Environment]::GetFolderPath("Desktop"),
[system.string]$IntuneProgramDir = "$env:APPDATA\Intune",
[System.String]$TempIcon = "$IntuneProgramDir\msedge.exe",
[bool]$ShortcutOnDesktop = $True,
[bool]$ShortcutInStartMenu = $True
)
$path = "C:\Program Files\icons"
If(!(test-path $path))
{
New-Item -ItemType Directory -Force -Path $path
}
$Base64String = '#base64string'
$Image = "C:\Program Files\icons\Alphen.ico"
[byte[]]$Bytes = [convert]::FromBase64String($Base64String)
[System.IO.File]::WriteAllBytes($Image,$Bytes)
#Test if icon is currently present, if so delete it so we can update it
$IconPresent = Get-ChildItem -Path $Desktop | Where-Object {$_.Name -eq "$ShortcutName.lnk"}
If ($null -ne $IconPresent)
{
Remove-Item $IconPresent.VersionInfo.FileName -Force -Confirm:$False
}
$WScriptShell = New-Object -ComObject WScript.Shell
If ((Test-Path -Path $IntuneProgramDir) -eq $False)
{
New-Item -ItemType Directory $IntuneProgramDir -Force -Confirm:$False
}
#Start download of the icon
Start-BitsTransfer -Source $IconURL -Destination $TempIcon
if ($ShortcutOnDesktop)
{
$Shortcut = $WScriptShell.CreateShortcut("$Desktop\$ShortcutName.lnk")
$Shortcut.TargetPath = $ShortcutUrl
$Shortcut.IconLocation = $TempIcon
$Shortcut.Save()
}
if ($ShortCutInStartMenu)
{
$Shortcut = $WScriptShell.CreateShortcut("$env:APPDATA\Microsoft\Windows\Start Menu\Programs\$ShortcutName.lnk")
$Shortcut.TargetPath = $ShortcutUrl
$Shortcut.IconLocation = $TempIcon
$Shortcut.Save()
}

Powershell/WScript Create Shortcut if not exist

I'm wondering if someone can help me? I've butchered a few powershell scripts I've found online that make shortcuts from $source to $destination. However, it appears to overwrite each time, and I only want it to create a .lnk on new.
The original source of the script is here and this is my current "non working" script.. I added the following, but it doesn't seem to work. I think I need to somehow get it to check the $destination and then continue if $file.lnk doesn't exist
If ($status -eq $false) {($WshShell.fso.FileExists("$Destination") + "*.lnk")
Full script:
function Create-ShortcutForEachFile {
Param(
[ValidateNotNullOrEmpty()][string]$Source,
[ValidateNotNullOrEmpty()][string]$Destination,
[switch]$Recurse
)
# set recurse if present
if ($Recurse.IsPresent) { $splat = #{ Recurse = $true } }
# Getting all the source files and source folder
$gci = gci $Source #splat
$Files = $gci | ? { !$_.PSisContainer }
$Folders = $gci | ? { $_.PsisContainer }
# Creating all the folders
if (!(Test-Path $Destination)) { mkdir $Destination -ea SilentlyContinue > $null }
$Folders | % {
$Target = $_.FullName -replace [regex]::escape($Source), $Destination
mkdir $Target -ea SilentlyContinue > $null
}
# Creating Wscript object
$WshShell = New-Object -comObject WScript.Shell
# Creating all the Links
If ($status -eq $false) {($WshShell.fso.FileExists("$Destination") + "*.lnk")
$Files | % {
$InkName = "{0}.lnk" -f $_.sBaseName
$Target = ($_.DirectoryName -replace [regex]::escape($Source), $Destination) + "\" + $InkName
$Shortcut = $WshShell.CreateShortcut($Target)
$Shortcut.TargetPath = $_.FullName
$Shortcut.Save()
}
}
}
Create-ShortcutForEachFile -Source \\myserver.domain.local\Folder1\Folder2\Test -Destination \\myserver2.domain.local\Folder1\Folder2\Test -Recurse
Hoping anyone can help me out, apologies for being a powershell/scripting noob.
My brother kindly reworked the script to suit better to my needs.
Here it is:
#################################################
<#
CREATE-SHORTCUT - creates shortcut for all files from a source folder
version : 1.0
Author :
Creation Date :
Modified Date :
#>
#------------------------------------------------------------[ variables ]----------------------------------------------------------
$sourceDir="D:\scripts\create-shortcut\source"
$targetDir="D:\scripts\create-shortcut\dest"
#-------------------------------------------------------------[ Script ]-----------------------------------------------------------
# get files/files from folder
$src_gci=Get-Childitem -path $sourceDir -Recurse
$src_files=$src_gci | ? { !$_.PSisContainer }
$src_folders=$src_gci | ? { $_.PSisContainer }
# create subfolders
$src_folders | Copy-Item -Destination { join-path $targetDir $_.Parent.FullName.Substring($sourceDir.Length) } -Force
# create shortcuts
$WshShell = New-Object -comObject WScript.Shell
$src_files | % {
$lnkName="{0}.lnk" -f $_.BaseName
$Target = ($_.DirectoryName -replace [regex]::escape($sourceDir), $targetDir) + "\" + $lnkName
$Shortcut = $WshShell.CreateShortcut($Target)
$Shortcut.TargetPath = $_.FullName
$Shortcut.Save()
# change to SourceFiles ModifiedDate #
$src_date=$_.LastWriteTime
Get-ChildItem $Target | % { $_.LastWriteTime = "$src_date" }
}

Powershell script not iterating through child folders

I sniped this script online and it works fine for converting the files in the parent folder. It does not however iterate through the child folders. I do not get any errors and I have verified all the folder permissions are correct. Additionally, I have scripts that are coded similar for *.docx and *.pptx files and they run successfully. This one however is not working as expected. Any ideas?
$path = "c:\converted\"
$xlFixedFormat = "Microsoft.Office.Interop.Excel.xlFixedFormatType" -as [type]
$excelFiles = Get-ChildItem -Path $path -include *.xls, *.xlsx -recurse
$objExcel = New-Object -ComObject excel.application
$objExcel.visible = $false
foreach($wb in $excelFiles)
{
$filepath = Join-Path -Path $path -ChildPath ($wb.BaseName + ".pdf")
$workbook = $objExcel.workbooks.open($wb.fullname, 3)
$workbook.Saved = $true
"converted $wb.fullname"
$workbook.ExportAsFixedFormat($xlFixedFormat::xlTypePDF, $filepath)
$objExcel.Workbooks.close()
#get rid of conversion copy
#Remove-Item $wb.fullname
}
$objExcel.Quit()
$excelFiles will contain subfolders, but your construction of $filepath uses only the original $path and current $wb.BaseName without taking into account that the current $wb.FullName may contain a longer path.
Replace
$filepath = Join-Path -Path $path -ChildPath ($wb.BaseName + ".pdf")
with
$filepath = $wb.fullname -replace $wb.extension,".pdf"

Create multiple shortcuts in different folders based on file name

Basically, we have a lot of .mht files (generated periodically with MicroStrategy) and we need to serve these files on different folders to apply security. To avoid space consumption, we thought of creating shortcuts on several folders.
The files all start with groupings of 4 digits and an underscore (e.g. 0001_0041, 0001_0043, etc.).
This is what I have now:
Get-Childitem -Path "C:\Users\Max\Google Drive\Portal\Mermaid" -Recurse -Include "0002*.mht"
Foreach-Object {
$ruta = Get-Childitem -Path "C:\Users\Max\Google Drive\Portal\Mermaid" -Recurse -Include "0002*.mht"
$nombre = Get-Childitem -Name "C:\Users\Max\Google Drive\Portal\Mermaid" -Recurse -Include "0002*.mht"
$ncorto = $nombre | ForEach-Object {$nombre.Substring(0,9)}
$container = "C:\Users\Max\Google Drive\Portal\Mermaid\MHT_Shortcuts\$ncorto"
if (!(Test-Path $container)) {
New-Item -ItemType directory -Path $container | Out-Null
}
$TargetFile = $ruta
$ShortcutFile = "$container\$nombre.lnk"
$WScriptShell = New-Object -ComObject WScript.Shell
$Shortcut = $WScriptShell.CreateShortcut($ShortcutFile)
$Shortcut.TargetPath = $TargetFile
$Shortcut.Save()
}
This works as long as there is only one file starting with 0002. However, they keep historic files that have the same name with timestamp.
If there are multiple files that start with 0002 (there will be as they keep historic versions of these files), I get the error:
Exception setting "TargetPath": "The parameter is incorrect. (Exception from
HRESULT: 0x80070057 (E_INVALIDARG))"
En C:\Users\Max\Desktop\MK_LNK_V01.ps1: 25 Character: 7
+ $Shortcut.TargetPath = $TargetFile
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : CatchFromBaseAdapterSetValueTI
Sorry if this is a duplicate, I couldn't find a post about this specific issue.
Here's a short example of how to create .lnk files for all files in a directory:
$shortcutPath = "C:\TextFiles"
$wshShell = New-Object -ComObject "WScript.Shell"
Get-ChildItem (Join-Path $shortcutPath "*.txt") | ForEach-Object {
$lnkFilename = Join-Path $shortcutPath ("{0}.lnk" -f [IO.Path]::GetFilenameWithoutExtension($_.FullName))
$shortcut = $wshShell.CreateShortcut($lnkFilename)
$shortcut.TargetPath = $_.FullName
$shortcut.Save()
}
Of course you will need to modify this example to suit your needs.
Based on the script that #Bill_Stewart provided, I added some lines to first delete the links, then create the containing folder based on the 1st 9 characters of the filename and create the shortcuts in it:
$shortcutPath = "C:\Origin"
$contenedor = "C:Destination"
$wshShell = New-Object -ComObject "WScript.Shell"
Get-ChildItem -Path $contenedor -Include *.lnk -File -Recurse | foreach { $_.Delete()}
Get-ChildItem (Join-Path $shortcutPath "*.mht") | ForEach-Object {
$nombre = $_.BaseName
$ncorto = $nombre.SubString(0, 9)
$destino = Join-Path $contenedor $ncorto
if (!(test-Path $destino)) {
New-Item -ItemType directory -Path $destino | Out-Null}
$lnkFilename = Join-Path $destino("{0}.lnk" -f [IO.Path]::GetFilenameWithoutExtension($_.FullName))
$shortcut = $wshShell.CreateShortcut($lnkFilename)
$shortcut.TargetPath = $_.FullName
$shortcut.Save()
This worked as a charm. Thanks all for your help.
The TargetPath property of a WshShortcut object expects a single path, not a list of paths. Also, I'd recommend moving everything that doesn't require repeated exectution outside the loop.
$app = New-Object -ComObject 'WScript.Shell'
$container = 'C:\shortcut\folder'
$path = 'C:\Users\Max\Google Drive\Portal\Mermaid'
if (!(Test-Path $container)) {
New-Item -Type Directory -Path $container | Out-Null
}
Get-Childitem -Path $path -Recurse -Include "0002*.mht" | Foreach-Object {
$ShortcutFile = "$container\$nombre.lnk" -f $_.BaseName
$Shortcut = $app.CreateShortcut($ShortcutFile)
$Shortcut.TargetPath = $_.FullName
$Shortcut.Save()
}

Delete files after conversion in Powershell

I'm very inexperienced in Powershell - but through trial and error I have managed to get a .doc/.docx to .pdf conversion working well for a specified folder and all subfolders.
$wdFormatPDF = 17
$word = New-Object -ComObject word.application
$word.visible = $false
$fileTypes = "*.docx","*.doc"
Get-ChildItem -Recurse -path "C:\test-acrobat" -include $fileTypes |
foreach-object `
{
$path = ($_.fullname).substring(0,($_.FullName).lastindexOf("."))
"Converting $path to pdf ..."
$doc = $word.documents.open($_.fullname)
$doc.saveas( $path, $wdFormatPDF)
$doc.close()
}
$word.Quit()
Now I'd like to be able to delete the original .doc/.docx files once they've been converted. On doing some searching I've found what I think would work:
{
remove-item $fileTypes # delete file from file-system
}
But I'd rather check than throw in a command to delete files...
Any help is greatly appreciated.
Philip
I would add the delete inside the foreach loop.
So you would get:
$wdFormatPDF = 17
$word = New-Object -ComObject word.application
$word.visible = $false
$fileTypes = "*.docx","*.doc"
Get-ChildItem -Recurse -path "C:\test-acrobat" -include $fileTypes |
foreach-object `
{
$path = ($_.fullname).substring(0,($_.FullName).lastindexOf("."))
Write-Host "Converting $path to pdf ..."
$doc = $word.documents.open($_.fullname)
$doc.saveas( $path, $wdFormatPDF)
$doc.close()
Remove-Item $_.fullname
}
$word.Quit()