Positioning of test-path in a PowerShell script - powershell

I have a script that sends an email when files are about to reach their max size.
The problem is, that I can't implement a validation check of what the script should do when a file is not found at the given path.
I know that I should implement:
if(!(Test-Path $item.Path))
{
"The file " + $item.Name + " is not found! <br />"
}
But I don't know where to place it exactly (since I'm getting errors all over the place).
The Code:
I start with retrieving the files from a config file:
$list = foreach ($file in $files)
{
$f = Get-Item $file.Path
New-Object -Type PSObject -Property #{
Name = $f.Name
Path = $file.Path
Size = ($f.Length/$byteSize)
}
}
then I loop through the file list and check their size:
foreach ($item in $list)
{
if($item.Size -gt $item.TriggerSize -And (Test-Path $item.Path))
{
#Write-Host $item.Name "Warning! File has reached it's max limit ("$item.Size.ToString(".00")"), The max size is" $item.MaxSize". The trigger size is: " $item.TriggerSize "`r`n"
$body +=
"The file " + $item.Name + " is reaching his max size!
<br /> Current size: <b>"+$item.Size.ToString(".00") + " " + $byteSize.Substring(1) + "</b>" +
"<br /> Maximum size: " + $item.MaxSize + " " + $byteSize.Substring(1) + "<br /><br />"
}
}
I tried implementing my error check on these places:
$list = foreach ($file in $files)
{
if(!(Test-Path $item.Path))
{
"The file " + $item.Name + " is not found! <br />"
}
$f = Get-Item $file.Path
New-Object -Type PSObject -Property #{
Name = $f.Name
Path = $file.Path
Size = ($f.Length/$byteSize)
}
}
and here
foreach ($item in $list)
{
if($item.Size -gt $item.TriggerSize -And (Test-Path $item.Path))
{
#Write-Host $item.Name "Warning! File has reached it's max limit ("$item.Size.ToString(".00")"), The max size is" $item.MaxSize". The trigger size is: " $item.TriggerSize "`r`n"
$body +=
"The file " + $item.Name + " is reaching his max size!
<br /> Current size: <b>"+$item.Size.ToString(".00") + " " + $byteSize.Substring(1) + "</b>" +
"<br /> Maximum size: " + $item.MaxSize + " " + $byteSize.Substring(1) + "<br /><br />"
}
if(!(Test-Path $item.Path))
{
"The file " + $item.Name + " is not found! <br />"
}
}
But I keep getting the error that it's at Get-Item that it can't find a file:
the name of the file that I wrote with a false path on purpose:
file123.exe
Error (at the line of the if(!(Test-Path $file.path)):
Get-Item : Cannot find path 'file123.exe' because it does not exist.

You are trying to error-handle but then your code still passes control to main logic. Instead, you should develop your control flow so that Get-Item will be called only when Test-Path returns true.
$list = foreach ($file in $files)
{
if (Test-Path $file.Path) {
$f = Get-Item $file.Path
New-Object -Type PSObject -Property #{
Name = $f.Name
Path = $f.Path
Size = ($f.Length/$byteSize)
}
} else {
"The file " + $file.path + " is not found! <br />"
}
}
And finally, PROOFREAD YOUR CODE! You've got $item.path tested but $file.path accessed. Given your foreach loop, you should have $file.path at both places.

You are only checking for file's existence and not catching not found exception. Here's a pseudo that should work:
foreach ($file in $files) {
try {
if (!(Test-Path $file.Path)) {
throw "File $($file.Path) not found"
}
# Rest of the logic
}
catch {
# log error $_.Exception.Message
}
}
Update: Send email whether file exists or not. This is pseudo, excuse syntax please.
Refactor the email sending functionality in separate method, say Send-Email($content). Then:
foreach file in files {
if !(Test-Path file.path) {
Send-Email -content "File $($file) does does not exist"
}
else {
// your logic here
if file.size > threshold {
Send-Email -content "File $($file) exceeded threshold size"
}
}
}

Related

Powershell create iso with defined directories

I'm using a function from Alistair McNair (https://github.com/TheDotSource/New-ISOFile/blob/main/New-ISOFile.ps1) as a starting point and trying to add some functionality to it. I would like to create some defined directories on iso that would then hold the data and copy specific data to that directory.
Here is the action to start the process:
$btnCreateISO.Add_Click({
$nicedate = get-date -UFormat %m-%d-%y #put in MM-DD-YY format
$isotitle = "WSUS-Offline-Server-$nicedate"
$isofilename = "WSUSSvrOffline-$nicedate.iso" #creates WSUS Offline Server such as update-11-14-2021.iso
$isofileandpath = $txtISOLocation.text+$isofilename # I:\WSUSSvrOffline-11-23-21.iso
$WSUSMetaDataPath = "c:\tools\wsusexport\"
$WSUSContentLocation = $txtWSUSContentLocation.Text # D:\WSUSContent\WsusContent that holds files
#ProgressBar information
$ProgressBar.Visible = $true
$ProgressBar.MarqueeAnimationSpeed = 20
$btnCreateISO.text = "Exporting"
Start-process -FilePath $txtWSUSUtil.text -ArgumentList #("export","$WSUSMetaDataPath\$nicedate-export.xml.gz","$WSUSMetaDataPath\$nicedate-export.log") -Wait
$btnCreateISO.text = "Exporting Completed"
$btnCreateISO.text = "Creating ISO"
New-ISOFile -WSUSContentLocation $WSUSContentLocation -WSUSMetaDataLocation $WSUSMetaDataPath -destinationIso $isofileandpath -title $isotitle -force -WhatIf
$btnCreateISO.text = "ISO Created"
Here is the code for the function:
...
function New-ISOFile {
#file originall from https://github.com/TheDotSource/New-ISOFile/blob/main/New-ISOFile.ps1 by Alistair McNair
[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact="Low")]
Param
(
[parameter(Mandatory=$true,ValueFromPipeline=$false)]
[string]$WSUSContentLocation,
[parameter(Mandatory=$true,ValueFromPipeline=$false)]
[string]$WSUSMetaDataLocation,
[parameter(Mandatory=$true,ValueFromPipeline=$false)]
[string]$destinationIso,
[Parameter(Mandatory=$false,ValueFromPipeline=$false)]
[string]$title = "untitled",
[Parameter(Mandatory=$false,ValueFromPipeline=$false)]
[switch]$force
)
begin {
Write-Verbose ("Function start.")
} # begin
process {
Write-Verbose ("Processing nested system " + $vmName)
## Set type definition
Write-Verbose ("Adding ISOFile type.")
$typeDefinition = #'
public class ISOFile {
public unsafe static void Create(string Path, object Stream, int BlockSize, int TotalBlocks) {
int bytes = 0;
byte[] buf = new byte[BlockSize];
var ptr = (System.IntPtr)(&bytes);
var o = System.IO.File.OpenWrite(Path);
var i = Stream as System.Runtime.InteropServices.ComTypes.IStream;
if (o != null) {
while (TotalBlocks-- > 0) {
i.Read(buf, BlockSize, ptr); o.Write(buf, 0, bytes);
}
o.Flush(); o.Close();
}
}
}
'#
## Create type ISOFile, if not already created. Different actions depending on PowerShell version
if (!('ISOFile' -as [type])) {
## Add-Type works a little differently depending on PowerShell version.
## https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/add-type
switch ($PSVersionTable.PSVersion.Major) {
## 7 and (hopefully) later versions
{$_ -ge 7} {
Write-Verbose ("Adding type for PowerShell 7 or later.")
Add-Type -CompilerOptions "/unsafe" -TypeDefinition $typeDefinition
} # PowerShell 7
## 5, and only 5. We aren't interested in previous versions.
5 {
Write-Verbose ("Adding type for PowerShell 5.")
$compOpts = New-Object System.CodeDom.Compiler.CompilerParameters
$compOpts.CompilerOptions = "/unsafe"
Add-Type -CompilerParameters $compOpts -TypeDefinition $typeDefinition
} # PowerShell 5
default {
## If it's not 7 or later, and it's not 5, then we aren't doing it.
throw ("Unsupported PowerShell version.")
} # default
} # switch
} # if
## Initialise image
Write-Verbose ("Initialising image object.")
try {
$image = New-Object -ComObject IMAPI2FS.MsftFileSystemImage -Property #{VolumeName=$title} -ErrorAction Stop
Write-Verbose ("initialised.")
} # try
catch {
throw ("Failed to initialise image. " + $_.exception.Message)
} # catch
## Create target ISO, throw if file exists and -force parameter is not used.
if ($PSCmdlet.ShouldProcess($destinationIso)) {
if (!($targetFile = New-Item -Path $destinationIso -ItemType File -Force:$Force -ErrorAction SilentlyContinue)) {
throw ("Cannot create file " + $destinationIso + ". Use -Force parameter to overwrite if the target file already exists.")
} # if
} # if
## Get WSUSMetaData content from specified path
Write-Verbose ("Fetching items from WSUSMetaData directory.")
try {
$WSUSMetaData = Get-ChildItem -LiteralPath $WSUSMetaDataLocation -ErrorAction Stop
Write-Verbose ("Got WSUSMetaData items.")
} # try
catch {
throw ("Failed to get WSUSMetaData items. " + $_.exception.message)
} # catch
## Get WSUSMetaData content from specified path
Write-Verbose ("Fetching items from WSUSContentData directory.")
try {
$WSUSContentData = Get-ChildItem -LiteralPath $WSUSContentLocation -ErrorAction Stop
Write-Verbose ("Got WSUSContentData items.")
} # try
catch {
throw ("Failed to get WSUSContentData items. " + $_.exception.message)
} # catch
##Create Directories on the ISO for the content
## Both the WSUSMetaData files go into this directory on the iso
$DirWSUSMetaData = $image.CreateDirectoryItem("WSUSMetaData")
$DirWSUSMetaData = $image.Root.AddTree($WSUSMetaDataLocation,$true)
## Add the WSUSMetaData to our image
Write-Verbose ("Adding WSUSMetaData to image.")
foreach($file in $WSUSMetaDataLocation){
try {
$image.Root.AddTree($file.fullname, $true)
}
catch {
throw ("Faile to add" + $file.fullname + ". " + $_.exeption.message)
}
}
##All the WSUSContent directories go into this directory on the iso
$DirWSUSContent = $image.CreateDirectoryItem("WSUSContentData") #create the directory WSUSContentData to hold all WSUS Content in the ISO
$DirWSUSContent = $image.Root.AddTree($WSUSContentLocation,$true) #add the location of the content to copy
## Add the WSUSMetaData to our image
Write-Verbose ("Adding WSUSMetaData to image.")
foreach($file in $WSUSContentLocation) {
try {
$image.Root.AddTree($file.FullName, $true)
} # try
catch {
throw ("Failed to add " + $file.fullname + ". " + $_.exception.message)
} # catch
} # foreach
## Write out ISO file
Write-Verbose ("Writing out ISO file to " + $targetFile)
try {
$result = $image.CreateResultImage()
[ISOFile]::Create($targetFile.FullName,$result.ImageStream,$result.BlockSize,$result.TotalBlocks)
} # try
catch {
throw ("Failed to write ISO file. " + $_.exception.Message)
} # catch
Write-Verbose ("File complete.")
## Return file details
return $targetFile
} # process
end {
Write-Verbose ("Function complete.")
} # end
...
Getting an error when I'm trying to create it:
What if: Performing the operation "New-ISOFile" on target " WSUSSvrOffline-11-23-21.iso".
Adding '11-23-21-export.xml.gz' would result in a result image having a size larger than the current configured limit.
At C:\tools\WSUSPowerShellStuff\WSUSOfflineServerGUIv1.ps1:153 char:9
+ $DirWSUSMetaData = $image.Root.AddTree($WSUSMetaDataLocation, ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
Faile to add.
At C:\tools\WSUSPowerShellStuff\WSUSOfflineServerGUIv1.ps1:162 char:14
+ ... throw ("Faile to add" + $file.fullname + ". " + $_.exepti ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Faile to add. :String) [], RuntimeException
+ FullyQualifiedErrorId : Faile to add.
So how do you change the configured limit?
Files Size of file giving error

Powershell - If file not in attachment

Using the below code how do I put a check in place that if the $FileName doesn't exist in the email then fail.
Ideally I want something like this -
Write-Host "Attachment $FileName does not exist for download."; exit 1
But I'm not sure where to put it in the code.
$EmailwithAttachments = [Microsoft.Exchange.WebServices.Data.EmailMessage]::Bind($service, $Email.Id, $emailProps)
Foreach ($File in $EmailwithAttachments.Attachments) {
If ($File.name -eq $FileName) {
Try {
#Just to be safe, remove any invaild characters from the attachment name
$FileName = $File.name -replace ("[{0}]" -f ([RegEx]::Escape([String][System.IO.Path]::GetInvalidFileNameChars())))
#Current can't handle Emails that are attacments, so we skip them
Write-Host "Attachment $FileName exists for download."
If ($File.contenttype -eq $null) {
Write-Warning "Attachment is an email, skipping"
$EMLAttachment = $TRUE
continue
}
Else {
$EMLAttachment = $FALSE
}
$File.load($SavePath + "\\" + $FileName)
If (($FileName -like "*.zip") -and $UnZipFiles) {$ZipFileNames += $SavePath + "\"+ $FileName}
}
Catch {
Send-ErrorReport -Subject "Attachment save path cannot be accessed" -body "Please verify the following path <B>$SavePath</B><BR>Full Error:<BR> $_" -HaltScript
}
}
}
If ($UnZipFiles) {
Try {
$shell = new-object -com shell.application
$Location = $shell.namespace($SavePath)
foreach ($ZipFile in $ZipFileNames) {
$ZipFolder = $shell.namespace($ZipFile)
$Location.Copyhere($ZipFolder.items())
Remove-item $ZipFile
}
}
Catch {
Send-ErrorReport -Subject "Attachment save path cannot be accessed" -body "Please verify the following path <B>$SavePath</B><BR>Full Error:<BR> $_" -HaltScript
}
}
}
}
$strFileName=($SavePath + "\\" + $FileName)
If (Test-Path $strFileName){
If ((Get-Content $strFileName) -eq "") {
"File Exists and is empty"; exit 1
}Else{
"File Exists and is stable."
}
}Else{
"File Does Not Exist"; exit 1
}
your $filename variable is empty, it should be declared before you can put it in your If statement, declare it before like this:
$EmailwithAttachments = [Microsoft.Exchange.WebServices.Data.EmailMessage]::Bind($service, $Email.Id, $emailProps)
$Filename = MyFileName
Foreach ($File in $EmailwithAttachments.Attachments) {
If ($File.name -eq $FileName)

Powershell Zip Folder Contents

I know a lot has been covered on zipping files using Powershell however I cannot find a method which does exactly what I need.
I want to be able to zip folders AND files into a .zip folder without having the parent folder inside the zip. So for example I have a folder named STUFF which contains files/folders, I want to zip this into a folder called STUFF.zip. This folders structure would then be STUFF.zip>files/folders NOT STUFF.zip>STUFF>files/folders as I currently get using this code...
function CountZipItems(
[__ComObject] $zipFile)
{
If ($zipFile -eq $null)
{
Throw "Value cannot be null: zipFile"
}
Write-Host ("Counting items in zip file (" + $zipFile.Self.Path + ")...")
[int] $count = CountZipItemsRecursive($zipFile)
Write-Host ($count.ToString() + " items in zip file (" `
+ $zipFile.Self.Path + ").")
return $count
}
function CountZipItemsRecursive(
[__ComObject] $parent)
{
If ($parent -eq $null)
{
Throw "Value cannot be null: parent"
}
[int] $count = 0
$parent.Items() |
ForEach-Object {
$count += 1
If ($_.IsFolder -eq $true)
{
$count += CountZipItemsRecursive($_.GetFolder)
}
}
return $count
}
function IsFileLocked(
[string] $path)
{
If ([string]::IsNullOrEmpty($path) -eq $true)
{
Throw "The path must be specified."
}
[bool] $fileExists = Test-Path $path
If ($fileExists -eq $false)
{
Throw "File does not exist (" + $path + ")"
}
[bool] $isFileLocked = $true
$file = $null
Try
{
$file = [IO.File]::Open(
$path,
[IO.FileMode]::Open,
[IO.FileAccess]::Read,
[IO.FileShare]::None)
$isFileLocked = $false
}
Catch [IO.IOException]
{
If ($_.Exception.Message.EndsWith(
"it is being used by another process.") -eq $false)
{
Throw $_.Exception
}
}
Finally
{
If ($file -ne $null)
{
$file.Close()
}
}
return $isFileLocked
}
function GetWaitInterval(
[int] $waitTime)
{
If ($waitTime -lt 1000)
{
return 100
}
ElseIf ($waitTime -lt 5000)
{
return 1000
}
Else
{
return 5000
}
}
function WaitForZipOperationToFinish(
[__ComObject] $zipFile,
[int] $expectedNumberOfItemsInZipFile)
{
If ($zipFile -eq $null)
{
Throw "Value cannot be null: zipFile"
}
ElseIf ($expectedNumberOfItemsInZipFile -lt 1)
{
Throw "The expected number of items in the zip file must be specified."
}
Write-Host -NoNewLine "Waiting for zip operation to finish..."
Start-Sleep -Milliseconds 1000 # ensure zip operation had time to start
[int] $waitTime = 0
[int] $maxWaitTime = 60 * 1000 # [milliseconds]
while($waitTime -lt $maxWaitTime)
{
[int] $waitInterval = GetWaitInterval($waitTime)
Write-Host -NoNewLine "."
Start-Sleep -Milliseconds $waitInterval
$waitTime += $waitInterval
Write-Debug ("Wait time: " + $waitTime / 1000 + " seconds")
[bool] $isFileLocked = IsFileLocked($zipFile.Self.Path)
If ($isFileLocked -eq $true)
{
Write-Debug "Zip file is locked by another process."
Continue
}
Else
{
Break
}
}
Write-Host
If ($waitTime -ge $maxWaitTime)
{
Throw "Timeout exceeded waiting for zip operation"
}
[int] $count = CountZipItems($zipFile)
If ($count -eq $expectedNumberOfItemsInZipFile)
{
Write-Debug "The zip operation completed succesfully."
}
ElseIf ($count -eq 0)
{
Throw ("Zip file is empty. This can occur if the operation is" `
+ " cancelled by the user.")
}
ElseIf ($count -gt $expectedCount)
{
Throw "Zip file contains more than the expected number of items."
}
}
function ZipFolder(
[IO.DirectoryInfo] $directory)
{
If ($directory -eq $null)
{
Throw "Value cannot be null: directory"
}
Write-Host ("Creating zip file for folder (" + $directory.FullName + ")...")
[IO.DirectoryInfo] $parentDir = $directory.Parent
[string] $zipFileName
If ($parentDir.FullName.EndsWith("\") -eq $true)
{
# e.g. $parentDir = "C:\"
$zipFileName = $parentDir.FullName + $directory.Name + ".zip"
}
Else
{
$zipFileName = $parentDir.FullName + "\" + $directory.Name + ".zip"
#$zipFileName = $directory.Name + ".zip"
#$zipFileName = $parentDir.FullName + ".zip"
}
If (Test-Path $zipFileName)
{
Throw "Zip file already exists ($zipFileName)."
}
Set-Content $zipFileName ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
$shellApp = New-Object -ComObject Shell.Application
$zipFile = $shellApp.NameSpace($zipFileName)
If ($zipFile -eq $null)
{
Throw "Failed to get zip file object."
}
[int] $expectedCount = (Get-ChildItem $directory -Force -Recurse).Count
$expectedCount += 1 # account for the top-level folder
$zipFile.CopyHere($directory.FullName)
#Get-ChildItem $directory | foreach {$zipFile.CopyHere($_.fullname)}
# wait for CopyHere operation to complete
WaitForZipOperationToFinish $zipFile $expectedCount
Write-Host -Fore Green ("Successfully created zip file for folder (" `
+ $directory.FullName + ").")
}
Usage
Remove-Item "H:\STUFF.zip"
[IO.DirectoryInfo] $directory = Get-Item "H:\STUFF"
ZipFolder $directory
Complete credit goes here for this code. I really appreciate any help I get, this capability is crucial to my project! Unfortunately I cannot use the Community Extension module as other PC's this will be run on does not have this module installed.
Thanks!
As per #mjolinor "H:\Stuff\", if you have .NET 4.5 installed you can run the following:
$src = "H:\Stuff\"
$dst = "H:\Stuff.zip"
[Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" )
[System.IO.Compression.ZipFile]::CreateFromDirectory($src, $dst)
New solution available with WMF 5 (well not that new ^^)
Compress-Archive -Path H:\stuff\* -DestinationPath H:\stuff.zip -Force
If you use PSCX Module you will use the line code below to obtain what you need:
write-zip h:\Stuff\* myzipfile.zip
I'm developing a simple module in Powershell, to more details https://github.com/julianosaless/powershellzip

Renaming .msg files using Powershell

We tend to drag and drop messages from outlook into Windows Explorer so I need to rename the default message filename so that the files are searchable/readable from Explorer.
I have managed to put together the following code that almost renames an outlook file on a network folder from the default "Subject.msg" to "To - Subject - ReceivedDate - hhmmss.msg". The only problem is that the rename step does not work as I believe the Outlook process is locking the file. I would appreciate help to avoid the locking and rename the files? Also, I am not sure what happens if there are multiple people in the To list, I would be happy to take the first name in the To list? Here is my effort:
$olMailItemPath = "W:\Marketing\Prospects\Emails\*"
Write-Host $olMailItemPath
$SourceFiles = Get-Item -path $olMailItemPath -include *.msg
$outlook = New-Object -comobject outlook.application
$namespace = $outlook.GetNamespace("MAPI")
function cleanName($aname)
{
$aname = $aname -replace "'"
$aname = $aname -replace ":"
$aname = $aname -replace "#"
$aname = $aname -replace "-"
return ($aname.trim())
}
function cleanSubject($subject)
{
$subject = $subject -replace 'Re:'
$subject = $subject
return (' - ' + $subject.trim() + ' - ')
}
foreach ($msg in $SourceFiles){
$olMailItem = $NameSpace.OpenSharedItem($msg)
$EmailTo = $olMailItem.To
$EmailSubject = $olMailItem.Subject
$DateRecieved = $olMailItem.ReceivedTime
$newfilename = (cleanName($EmailTo)) + (cleanSubject($EmailSubject)) + $DateRecieved.ToString("yyyyMMdd - hhmmss") + ".msg"
# Write-Host "Email Sent To: $EmailTo "
# Write-Host "Subject: $EmailSubject "
# Write-Host "Date Recieved: $DateRecieved"
Write-Host $msg
Write-Host $newfilename
Rename-Item $msg $newfilename
}
p.s. [Inserted # 18 Jun 2013] In answer to Athom, I know Outlook is locking the file as I get the following error:
Rename-Item : The process cannot access the file because it is being used by another process.
At C:\Users\Bertie\Dropbox\Programming\Powershell\Rename Outlook Messages.ps1:41 char:16
+ Rename-Item <<<< -path $msg -newname $newFileName
+ CategoryInfo : WriteError: W:\Marketing\Prospects\Emails\new.msg:String) [Rename-Item], IOException
+ FullyQualifiedErrorId : RenameItemIOError,Microsoft.PowerShell.Commands.RenameItemCommand
However, when I close outlook (which is initiated by the powershell script), I can then run the Rename-Item command and it run's successfully.
How's this?
Essentially the changes I have mades are:
Your renaming loop now throws its output to a hashtable.
Stop-Process kills Outlook.
Another loop then does the renaming.
# Declare the hastable to store the names, then generate the names.
$nameHash = #{}; Foreach ($msg in $SourceFiles){
# Do the Outlook thing
$olMailItem = $NameSpace.OpenSharedItem($msg)
$EmailTo = $olMailItem.To
$EmailSubject = $olMailItem.Subject
$DateRecieved = $olMailItem.ReceivedTime
$newfilename = (cleanName($EmailTo)) + (cleanSubject($EmailSubject)) + $DateRecieved.ToString("yyyyMMdd - hhmmss") + ".msg"
# Write-Host "Email Sent To: $EmailTo "
# Write-Host "Subject: $EmailSubject "
# Write-Host "Date Recieved: $DateRecieved"
# Store the names
$nameHash.Add("$msg","$newfilename")
}
# Kill Outlook.. Then wait....
Stop-Process -Name Outlook -Force
Start-Sleep -m 500 # You might be able to remove this - depends how beefy your CPU is.
# Rename
ForEach ($item in $nameHash.GetEnumerator()) {
# Testing >>-->
echo $item.Name
echo $item.Value
# <--<< Testing
Rename-Item $item.Name $item.Value
}

How to set variable with list's metadata (like customerID)?

How do I set a metadata (say CustomerID or Skills) with PowerShell? I am trying to fill CustID. Please suggest.....
$siteURL="http://Server"
$site=Get-SPSite $siteURL
$web=$site.RootWeb
$collFiles=$web.GetFolder("DocLib_OR_List").Files
$count=$collFiles.Count
while($count -ne 0)
{
$CustID= $collFiles[$count-1]["CustomerID"]
so forth......
}
Solved it. Working code:
$siteURL="http://Server"
$docLib = "My Doc Lib"
$site=Get-SPSite $siteURL
$web=$site.RootWeb
$collFiles=$web.GetFolder($docLib).Files
$count=$collFiles.Count
while($count -ne 0)
{
$item = $collFiles[$count-1].Item
$DocSet = $item["Region"]
Write-Host "$DocSet is the doc set. $collFiles[$count-1].Name is name"
$collFiles[$count-1].MoveTo($siteURL + "/" + $docLib + "/" + $DocSet + "/" + $collFiles[$count-1].Name, $true)
$count--
}
This is the final working code.
$siteURL="http://Server"
$docLib = "My Doc Lib"
$site=Get-SPSite $siteURL
$web=$site.RootWeb
$collFiles=$web.GetFolder($docLib).Files
$count=$collFiles.Count
while($count -ne 0)
{
$item = $collFiles[$count-1].Item
$DocSet = $item["Region"]
Write-Host "$DocSet is the doc set. $collFiles[$count-1].Name is name"
$collFiles[$count-1].MoveTo($siteURL + "/" + $docLib + "/" + $DocSet + "/" + $collFiles[$count-1].Name, $true)
$count--
}