Got this script running. Nearly completed my mission to print attachments from it that land in a specific subfolder of outlook
$OutputFolder = 'C:\tests';
$outlook = New-Object -ComObject Outlook.Application;
$olFolderInbox = 6;
$ns = $outlook.GetNameSpace("MAPI");
$inbox = $ns.GetDefaultFolder($olFolderInbox);
$inbox.Folders `
| ? Name -eq 'colour' `
| % Items `
| % Attachments `
| % {
$OutputFileName = Join-Path -Path $OutputFolder -ChildPath $_.FileName;
if (Test-Path $OutputFileName) {
$FileDirectoryName = [System.IO.Path]::GetDirectoryName($OutputFileName);
$FileNameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($OutputFileName);
$FileExtension = [System.IO.Path]::GetExtension($OutputFileName);
for ($i = 2; Test-Path $OutputFileName; $i++) {
$OutputFileName = "{0} ({1}){2}" -f (Join-Path -Path $FileDirectoryName -ChildPath $FileNameWithoutExtension), $i, $FileExtension;
}
}
Write-Host $OutputFileName;
$_.SaveAsFile($OutputFileName)
}
Remove-Item -Path C:\tests\*.jpg
Dir C:\tests\ | Out-Printer -name xerox-b8
Remove-Item -Path C:\tests\*.*
when i try to pipe the objects to print i am getting XML printing out, or just the directory contents
I have tried:
select-object (wrong)
get-childitem (wrong)
DIR C:\tests\*.* (only returns directory listing printout)
These either return a load of XML rubbish or just a directory listing,
How can i pipe the contents of a folder to a printer using powershell, surely this can be done
Related
I am trying to build a script that can do the following
When I open the powershell script
it should ask me for a path where the files are located e.g.
C:\SearchPath\DateOfToday
Daily there will be a new folder e.g. 20221214.
Maybe it is possible to specify the path and the script will get today's date by itself or maybe just opening a windows explorer so I can select the SourceFolder.
A file must be copied e.g. Test.xmr and then renamed to Test.$xmr
some more files should be collected like
jpl, eml, html, pdf, cml, xmr, $xmr and xml
the collected files should be moved to the folder
C:\AnotherFolder\
What I have so far is this
$SourceFolder = "\\Path1\Dateoftoday"
$DestFolder = '\\Path2' #Path to Destination Folder
[array]$FileList = gci -Path $SourceFolder -Recurse -File -Filter "ABC.xmr"
[array]$FileList = gci -Path $SourceFolder -Recurse -File -Filter "ABC.jpl"
[array]$FileList = gci -Path $SourceFolder -Recurse -File -Filter "ABC.eml"
[array]$FileList = gci -Path $SourceFolder -Recurse -File -Filter "ABC.html"
[array]$FileList = gci -Path $SourceFolder -Recurse -File -Filter "ABC.pdf"
[array]$FileList = gci -Path $SourceFolder -Recurse -File -Filter "ABC.cml"
[array]$FileList = gci -Path $SourceFolder -Recurse -File -Filter "ABC.xml"
ForEach ($F in $FileList) {
Copy-Item $F.FullName (Join-Path $DestFolder ($F.Name))
}
I can specify the path and the filenames and then run it.
Sorry if it's basic, but I'm new at powershell.
Looks like you just need this:
$today = '{0:yyyyMMdd}' -f (Get-Date)
$SourceFolder = "\\Path1\$today"
$DestFolder = '\\Path2' #Path to Destination Folder
$filePattern = '*.xmr', '*.jpl', '*.eml', '*.html', '*.pdf', '*.cml', '*.xml', '*.$xmr'
# unclear about your question 2)..
# do we need to copy a file to the $SourceFolder first ??
# Copy-Item -Path 'X:\Somewhere\Test.xmr' -Destination (Join-Path -Path $SourceFolder -ChildPath 'Test.$xmr')
# copy all chosen files to the destination folder
Get-ChildItem -LiteralPath $SourceFolder -Recurse -File -Include $filePattern | ForEach-Object {
$_ | Copy-Item -Destination $DestFolder
}
As per your comment, hopefully this is what you need:
$today = '{0:yyyyMMdd}' -f (Get-Date)
$SourceFolder = "\\Path1\$today"
$DestFolder = '\\Path2' #Path to Destination Folder
$extensions = 'xmr', 'jpl', 'eml', 'html', 'pdf', 'cml', 'xml'
# ask for the filename
$baseName = Read-Host 'Please enter the file name without extension'
if (![string]::IsNullOrWhiteSpace($baseName)) {
# construct the filenames to copy
$pattern = $extensions | ForEach-Object { '{0}.{1}' -f $baseName.Trim(), $_ }
# copy all chosen files to the destination folder
Get-ChildItem -LiteralPath $SourceFolder -Recurse -File |
Where-Object { $pattern -contains $_.Name } | ForEach-Object {
# rename the extensions by prefixing it with a dollar sign ($)
$targetFile = Join-Path -Path $DestFolder -ChildPath ('{0}.${1}' -f $_.BaseName, $_.Extension.TrimStart("."))
$_ | Copy-Item -Destination $targetFile
# if you want ONLY the .xmr file to be renamed with as .$xmr use this instead:
# if ($_.Extension -eq '.xmr') {
# $targetFile = Join-Path -Path $DestFolder -ChildPath ('{0}.${1}' -f $_.BaseName, $_.Extension.TrimStart("."))
# $_ | Copy-Item -Destination $targetFile
# }
# else {
# $_ | Copy-Item -Destination $DestFolder
# }
}
}
Edit
As you commentd you want to remove the leftover .xmr and .att files after copying, here the code that does that too
$today = '{0:yyyyMMdd}' -f (Get-Date)
$SourceFolder = "\\Path1\$today"
$DestFolder = '\\Path2' #Path to Destination Folder
$extensions = 'xmr', 'jpl', 'eml', 'html', 'pdf', 'cml', 'xml', 'att'
# ask for the filename
$baseName = Read-Host 'Please enter the file name without extension'
if (![string]::IsNullOrWhiteSpace($baseName)) {
# construct the filenames to copy
$pattern = $extensions | ForEach-Object { '{0}.{1}' -f $baseName.Trim(), $_ }
# copy all chosen files to the destination folder
(Get-ChildItem -LiteralPath $SourceFolder -Recurse -File) |
Where-Object { $pattern -contains $_.Name } | ForEach-Object {
# rename the extensions by prefixing it with a dollar sign ($)
$targetFile = Join-Path -Path $DestFolder -ChildPath ('{0}.${1}' -f $_.BaseName, $_.Extension.TrimStart("."))
$_ | Copy-Item -Destination $targetFile
# if you want ONLY the .xmr file to be renamed with as .$xmr use this instead:
# if ($_.Extension -eq '.xmr') {
# $targetFile = Join-Path -Path $DestFolder -ChildPath ('{0}.${1}' -f $_.BaseName, $_.Extension.TrimStart("."))
# $_ | Copy-Item -Destination $targetFile
# }
# else {
# $_ | Copy-Item -Destination $DestFolder
# }
# remove leftover .XMR and .ATT files
if ($_.Extension -match '\.(xmr|att)$') { $_ | Remove-Item -Force }
}
}
Good day!!
Maybe we can help you with this:
First of all you need to ask for the path and we have two ways to do this (maybe more) but those are the ways I know
The first option is the simple, using the Read-Host Cmdlet:
$path = Read-Host "Please type the path of the folder"
The second option is more complicated and use dotnet framework: (to ask for the destination just change the last two variables with destination instead of sourcePath)
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$box = New-Object System.Windows.Forms.Form
$box.Text = 'Script Execution'
$box.Size = New-Object System.Drawing.Size(300,200)
$box.StartPosition = 'CenterScreen'
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(75,120)
$okButton.Size = New-Object System.Drawing.Size(75,23)
$okButton.Text = 'OK'
$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$box.AcceptButton = $okButton
$box.Controls.Add($okButton)
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Point(150,120)
$cancelButton.Size = New-Object System.Drawing.Size(75,23)
$cancelButton.Text = 'Cancel'
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$box.CancelButton = $cancelButton
$box.Controls.Add($cancelButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'Please type the path of the files:'
$box.Controls.Add($label)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(260,20)
$box.Controls.Add($textBox)
$box.Topmost = $true
$box.Add_Shown({$textBox.Select()})
$result = $box.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$sourcePath = $textBox.Text
$sourcePath
}
Once we have the path we can copy the files to do it we can use Copy-item
(I'm not sure if you want to rename the original files or the final files, anyway if you want to rename the last files just use rename-item cmdlet)
$fileList = #(
Get-ChildItem -Path $sourcePath -Recurse -include "*.jpl", "*.eml", "*.html", "*.pdf", "*.cml", "*.xml"
)
foreach ($f in $fileList){
Copy-Item -Path $f.fullname -Destination "$destPath\$f.name"
}
And this should be enough, i'm not really sure about the $fileList part maybe I made some typo, sorry in this case.
Have a nice day!
I have this type of code in a backup script.
while($true){
$time = Get-Date -Format HH:mm:ss
$dateCheck = (Get-Date).AddDays(-0).ToString('dd-MM-yyyy')
[int]$check = $check
Get-ChildItem 'C:\fleet-integrator-installer-DHL2\work\matilda\14\done' -File |
Sort-Object -Property CreationTime -Descending |
Select-Object -First 1 |
Copy-Item -Destination \\Ict_nas\dhl\$dateCheck -Force
if($time -eq ('23:59:00')){
$check = $check - $check
}
if($time -eq ('23:59:30') -and $check -eq 0){
New-Item -ItemType "directory" -Path "\\Ict_nas\dhl" -Name $dateCheck | Out-Null
$check++
}
if($time -eq ('00:00:00')){
$fileCount = ( Get-ChildItem C:\fleet-integrator-installer-DHL2\work\matilda\14\done ).Count;
$EmailFrom = "..."
$EmailTo = "..."
$Subject = "Backup DHL Integrator -> IT NAS"
$Body = "The backup was succesful, $fileCount files are copied to the NAS"
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("", "")
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
Get-ChildItem -Path C:\fleet-integrator-installer-DHL2\work\matilda\14\done -Include *.* -File -Recurse | foreach { $_.Delete()}
}
}
It is creating automaticly an folder with the date of today on a NAS.
When i run the code separate it is working fine but in the script it is just creating a file with the date of today...
Anyone tips?
Thanks
You are copying to the directory before creating it:
Copy-Item -Destination \\Ict_nas\dhl\$dateCheck -Force
Because the directory does not exist (yet), the destination is interpreted as a file name. So the source file is copied to a file of that name.
I am not sure what your $check logic is supposed to do, but basically you have 2 options:
A) Create the directory first, before copying to it
New-Item "\\Ict_nas\dhl\$dateCheck" -Type Directory | Out-Null
Get-ChildItem 'C:\fleet-integrator-installer-DHL2\work\matilda\14\done' -File |
sort CreationTime -Descending | select -First 1 |
Copy-Item \\Ict_nas\dhl\$dateCheck
B) Specify a full file path for copying
Get-ChildItem 'C:\fleet-integrator-installer-DHL2\work\matilda\14\done' -File |
sort CreationTime -Descending | select -First 1 | foreach {
Copy-Item $_.FullName "\\Ict_nas\dhl\$dateCheck\$($_.Name)"
}
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" }
}
Hello and thank you in advance. Currently I have a script running that downloads files from one location to another. I'm trying to clean up the script to only download files that have _Lthumb in the file name. Any help would be greatly appreciated.
The following line in which I added is causing the problems. Wheni remove it, the script runs fine, but it doesn't filter the data by _Lthumb:
| Where-Object {$_.Name -Match '*_Lthumb'}
Here is the script, including the portion above that breaks it:
if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {
Add-PSSnapin Microsoft.SharePoint.PowerShell;
}
######################## Start Variables ########################
$destination = "\\pulse-dev.hinshawad.com\C$\ProfilePhotos\ProfilePictures"
$webUrl = "http://mysites.hinshawad.com"
$listUrl = "http://mysites.hinshawad.com/user photos/profile pictures/"
##############################################################
$web = Get-SPWeb -Identity $webUrl
$list = $web.GetList($listUrl)
function ProcessFolder {
param($folderUrl)
$folder = $web.GetFolder($folderUrl)
foreach ($file in $folder.Files | Where-Object {$_.Name -Match '*_Lthumb'} ) {
#Ensure destination directory
$destinationfolder = $destination + "/" + $folder.Url
if (!(Test-Path -path $destinationfolder))
{
$dest = New-Item $destinationfolder -type directory
}
#Download file
$binary = $file.OpenBinary()
#$stream = New-Object System.IO.FileStream($destinationfolder + "/" + $file.Name), Create
$stream = New-Object System.IO.FileStream($destinationfolder + "/" + ($file.Name -replace "_Lthumb")), Create
$writer = New-Object System.IO.BinaryWriter($stream)
$writer.write($binary)
$writer.Close()
}
}
#Download root files
ProcessFolder($list.RootFolder.Url)
#Download files in folders
#foreach ($folder in $list.Folders) {
#ProcessFolder($folder.URL)
#}
I have a script i scraped from other scripts. It works except i am quite new to powershell and am a sys admin not a dev, (but reading my ass off). I can get the scrtipt to work downloading attachments from inbox in outlook but need it to download attachments from a subfolder instead:
############################# Outlook Call ##############################
$olFolderInbox = 6
$outlook = new-object -com outlook.application;
$ns = $outlook.GetNameSpace("MAPI");
$inbox = $ns.GetDefaultFolder($olFolderInbox)
$messages = $inbox.items
write-host $messages.count
$messcount = $messages.count
foreach($message in $messages){
##############Save Attachments################
$filepath = "c:\attachments\"
$message.attachments|foreach {
Write-Host $_.filename
$attr = $_.filename
$_.saveasfile((Join-Path $filepath $_.filename))
$a = $_.filename
If ($a.Contains("")) {
$_.saveasfile((Join-Path $filepath $a))
}
}
}
###########END##########
Any Ideas anyone? Would be massively grateful.
$OutputFolder = 'C:\tests';
$ErrorActionPreference= 'silentlycontinue'
$outlook = New-Object -ComObject Outlook.Application;
$olFolderInbox = 6;
$ns = $outlook.GetNameSpace("MAPI");
$inbox = $ns.GetDefaultFolder($olFolderInbox);
$inbox.Folders `
| ? Name -eq 'colour' `
| % Items `
| % Attachments `
| % {
$OutputFileName = Join-Path -Path $OutputFolder -ChildPath $_.FileName;
if (Test-Path $OutputFileName) {
$FileDirectoryName = [System.IO.Path]::GetDirectoryName($OutputFileName);
$FileNameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($OutputFileName);
$FileExtension = [System.IO.Path]::GetExtension($OutputFileName);
for ($i = 2; Test-Path $OutputFileName; $i++) {
$OutputFileName = "{0} ({1}){2}" -f (Join-Path -Path $FileDirectoryName -ChildPath $FileNameWithoutExtension), $i, $FileExtension;
}
}
Write-Host $OutputFileName;
$_.SaveAsFile($OutputFileName)
}
Remove-Item -Path C:\tests\*.jpg
Remove-Item -Path C:\tests\*.png
Start-Process –FilePath “c:\tests\*.docx” –Verb Print -PassThru
Start-Process –FilePath “c:\tests\*.xlsx” –Verb Print -PassThru
Start-Process –FilePath “c:\tests\*.doc” –Verb Print -PassThru
Start-Process –FilePath “c:\tests\*.xls” –Verb Print -PassThru
Start-Process –FilePath “c:\tests\*.pptx” –Verb Print -PassThru
Start-Process –FilePath “c:\tests\*.ppt” –Verb Print -PassThru
Start-Process –FilePath “c:\tests\*.xls” –Verb Print -PassThru
Start-Process –FilePath “c:\tests\*.msg” –Verb Print -PassThru
Start-Process –FilePath “c:\tests\*.xlsm” –Verb Print -PassThru
Start-Process –FilePath “c:\tests\*.rtf” –Verb Print -PassThru
Start-Process –FilePath “c:\tests\*.pdf” –Verb Print -PassThru `
%{sleep 3;$_}
Remove-Item -Path C:\tests\*.*
This accomplishes what i need, i might put a kill process in after each one just to make sure there is no doc stuck.
But - The 1 thing left to accomplish is i need this to write to a non default printer and not change the existing default? This runs on a server with a vbscript already running utilizing default printer so it will mess that up if it changes.
As usual with COM Objects, it's pretty ugly to do.
You're supposed to do it like the question here, but I can't get that to work at all. $Inbox.Folders['FolderName'] returns nothing, and $Inbox.Folders('FolderName') returns an error.
Here's how I can get it to work. I'm on PowerShell v4 with Office 2013.
Say you've got a folder at \\Inbox\eReports\Amazon\StatsReports, and you want all the messages in it.
$Messages = $inbox.Folders `
| ? Name -eq 'eReports' `
| % Folders `
| ? Name -eq 'Amazon' `
| % Folders `
| ? Name -eq 'StatsReports' `
| % Items;
Note that the way I'm using ForEach-Object and Where-Object require PowerShell v3. Under earlier versions this would be considerably more verbose.
Here's a full version of the script that works for me on Win 7 x64/PowerShell v4/Office 2013. I've tested it on a few different folders, so it should work.
It will automatically rename files with duplicate names, following the Windows convention of adding a (2), then a (3) and so on.
$OutputFolder = 'C:\OutputFolder';
$outlook = New-Object -ComObject Outlook.Application;
$olFolderInbox = 6;
$ns = $outlook.GetNameSpace("MAPI");
$inbox = $ns.GetDefaultFolder($olFolderInbox);
$inbox.Folders `
| ? Name -eq 'eReports' `
| % Folders `
| ? Name -eq 'Amazon' `
| % Folders `
| ? Name -eq 'StatsReports' `
| % Items `
| % Attachments `
| % {
$OutputFileName = Join-Path -Path $OutputFolder -ChildPath $_.FileName;
if (Test-Path $OutputFileName) {
$FileDirectoryName = [System.IO.Path]::GetDirectoryName($OutputFileName);
$FileNameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($OutputFileName);
$FileExtension = [System.IO.Path]::GetExtension($OutputFileName);
for ($i = 2; Test-Path $OutputFileName; $i++) {
$OutputFileName = "{0} ({1}){2}" -f (Join-Path -Path $FileDirectoryName -ChildPath $FileNameWithoutExtension), $i, $FileExtension;
}
}
Write-Host $OutputFileName;
$_.SaveAsFile($OutputFileName);
}