I accidentally delete my email account and so all of the emails in that account. Is there a chance to recover the emails? How can I recover it? Thanks.
Four months ago I would have agreed with Om3r's comment giving the location of the Outlook stores. But I bought a new laptop in December and now the Outlook files are not where all the documentation says they should be. Worse, I cannot reach the folders containing the Outlook files using File Explorer although I can find them with VBA.
The macro below searches drive C for files with an extension of OST or PST. I cannot promise this macro will find your lost store but, if it is still on your disc, it will find it. If you find the missing store, you will probably have to use VBA to move it to somewhere accessible.
Copy the macro below to a macro-enabled workbook and run it. While it is running the active worksheet will look like:
1923 Folders to search
327 Folders searched
Store Size Date Folder
$ILJARJ0.pst 212 28Mar20 C:\$Recycle.Bin\S-1-5-21-3957073674-21115239-22921093-1001
$IMS96DJ.pst 212 28Mar20 C:\$Recycle.Bin\S-1-5-21-3957073674-21115239-22921093-1001
The top two rows give a crude progress indicator. On my laptop, the routine ends with 69190 folders searched. I do not know why there are PST files in my recycle bin. I did nothing relevant on 28 March. When the routine has finished, there will be a auto-fitted list of every store the macro found. On my laptop none are where I would expect and some are duplicates. I hope you find your store.
Option Explicit
Sub SearchForStoresOnC()
' Searches drive C for files with an extension of PST or OST
' Warning: overwrites the active workbook
Dim ErrNum As Long
Dim FileAttr As Long
Dim FileName As String
Dim FldrName As String
Dim RowCrnt As Long
Dim ToSearch As Collection
Cells.EntireRow.Delete
Range("A1").Value = 0
Range("A2").Value = 0
Range("B1").Value = "Folders to search"
Range("B2").Value = "Folders searched"
Range("B4").Value = "Store"
With Range("C4")
.Value = "Size"
.HorizontalAlignment = xlRight
End With
With Range("D4")
.Value = "Date"
.HorizontalAlignment = xlRight
End With
Range("E4") = "Folder"
RowCrnt = 5
Set ToSearch = New Collection
' Load ToSearch with drive to search.
ToSearch.Add "C:"
Do While ToSearch.Count > 0
FldrName = ToSearch(1)
ToSearch.Remove 1
Err.Clear
ErrNum = 0
On Error Resume Next
' Stores are unlikely to be hidden but can be in folders that are hidden
FileName = Dir$(FldrName & "\*.*", vbDirectory + vbHidden + vbSystem)
ErrNum = Err.Number
On Error GoTo 0
If ErrNum <> 0 Then
'Debug.Print "Dir error: " & FldrName
Else
Do While FileName <> ""
If FileName = "." Or FileName = ".." Then
' Ignore pointers
Else
Err.Clear
On Error Resume Next
FileAttr = GetAttr(FldrName & "\" & FileName)
ErrNum = Err.Number
On Error GoTo 0
If ErrNum = 0 Then
' Ignore file and folders which give errors
If (FileAttr And vbDirectory) = 0 Then
' File
'Debug.Assert False
Select Case Right$(FileName, 4)
Case ".pst", ".ost"
Cells(RowCrnt, "B").Value = FileName
With Cells(RowCrnt, "C")
.Value = FileLen(FldrName & "\" & FileName)
.NumberFormat = "#,##0"
End With
With Cells(RowCrnt, "D")
.Value = FileDateTime(FldrName & "\" & FileName)
.NumberFormat = "dmmmyy"
End With
Cells(RowCrnt, "E").Value = FldrName
RowCrnt = RowCrnt + 1
End Select
Else
' Directory
ToSearch.Add FldrName & "\" & FileName
End If ' File or Directory
Else
'Debug.Print "FileAttr error: " & FldrName & "\" & FileName
End If ' FileAttr does not give an error
End If ' Pointer or (File or Directory)
FileName = Dir$
Loop ' For each pointer, file and sub-directory in folder
End If ' Dir$ gives error
Range("A1") = ToSearch.Count
Range("A2") = Range("A2") + 1
DoEvents
Loop 'until ToSearch empty
Columns.AutoFit
End Sub
Related
I'm trying to select around 17k files in a specific folder containing around 22k from a list in excel. The list has the name and extension of all files and nothing more.
I've tried this code but no luck.
Sub DeletePics()
Dim picRNG As Range, pic As Range, picPATH As String
picPATH = "path"
Set picRNG = Sheets("Sheet1").Range("A1:A17108").SpecialCells(xlConstants)
On Error Resume Next
For Each pic In picRNG
If pic.Offset(, 1) = "Delete" Then
If Len(Dir(picPATH & pic.Value)) > 0 Then
Kill picPATH & pic.Value
pic.Offset(, 2).Value = "Deleted"
Else
pic.Offset(, 2).Value = "Not Found"
End If
End If
Next pic
End Sub
Ok, so we need to create a GPO that allows our users to only use specific programs.
GPO Location:
User Configuration
Policies
Administrative Templates [...]
System
Run only specified Windows applications
Then setting the GPO to enabled and clicking on List of allowed applications --> Show...
I have created an excel spreadsheet containing the names of all the programs and their associated executable files with other pertinent information so that we can easily organize, add, delete, etc. the executable files that we need to allow our users access to.
This spreadsheet then dumps all the executable files into a text file.
Here is an example of what the text file looks like:
Acrobat.exe
chrome.exe
calc.exe
.
.
.
There are a lot of entries and these are likely subject to change. What I am trying to do is create a script that will take that text file and populate the GPO automatically. I don't care if we have to open the window and then run it, it does not need to run from the task scheduler (although that would be amazing if someone has that code ready). We just need it to populate this ridiculous amount of executable filenames into the fields.
Here is code I found (VBScript) that when run, should populate the fields automatically, however I cannot get it to run in the Group Policy Management Editor (it runs in the windows explorer window instead and ends up searching for some of the files)
' Open the text file, located in the same path as the script
Set objFSO = CreateObject("Scripting.FileSystemObject")
strPath = Mid(Wscript.ScriptFullName, 1, InStrRev(Wscript.ScriptFullName, wscript.ScriptName) -1)
Set objFile = objFSO.OpenTextFile(strPath & "appList.txt")
' Activate the "Show Contents" window with the "List of allowed applications".
' Note the window must be opened already and we should have selected where in
' the list we want to enter the data before running the script
set WshShell = WScript.CreateObject("WScript.Shell")
WScript.Sleep 1000
WshShell.AppActivate "Show Contents"
' Read the file line by line
Do While objFile.AtEndOfStream <> True
' Each line contains one EXE name
exeName = objFile.ReadLine
' Escape forbidden chars { } [ ] ( ) + ^ % ~
exeName = Replace(exeName, "[", "{[}")
exeName = Replace(exeName, "]", "{]}")
exeName = Replace(exeName, "(", "{(}")
exeName = Replace(exeName, ")", "{)}")
exeName = Replace(exeName, "+", "{+}")
exeName = Replace(exeName, "^", "{^}")
exeName = Replace(exeName, "%", "{%}")
exeName = Replace(exeName, "~", "{~}")
' Send the EXE name to the window
WScript.Sleep 100
WshShell.SendKeys exeName
' Move to the next one
WshShell.SendKeys "{TAB}"
Loop
objFile.Close
from: http://blogs.msdn.com/b/alejacma/archive/2011/03/24/how-to-update-quot-run-only-specified-windows-applications-quot-gpo-programmatically-vbscript.aspx
"C:\Windows\System32\GroupPolicy\User\Registry.pol"
Is where my policies are stored. It's a semi text file. Try writing to that file.
Ok, so I tried it many different ways. If anyone is looking for an answer to do this, this is the way I've figured it out and the way I've decided to proceed. I will post all relevant code below.
In Excel, the format of my table is as follows:
(With obviously WAY more entries)
Here is the VBA code I used to turn the data from this file into the proper format for the registry key:
VBA - In Excel
Public Sub ExportToTextFile(FName As String, _
Sep As String, SelectionOnly As Boolean, _
AppendData As Boolean)
Dim WholeLine As String
Dim FNum As Integer
Dim RowNdx As Long
Dim ColNdx As Integer
Dim StartRow As Long
Dim EndRow As Long
Dim StartCol As Integer
Dim EndCol As Integer
Dim CellValue As String
Application.ScreenUpdating = False
On Error GoTo EndMacro:
FNum = FreeFile
StartRow = 2
If SelectionOnly = True Then
With Selection
StartCol = .Cells(2).Column
EndRow = .Cells(.Cells.Count).Row
EndCol = .Cells(2).Column
End With
Else
With ActiveSheet.UsedRange
StartCol = .Cells(2).Column
EndRow = .Cells(.Cells.Count).Row
EndCol = .Cells(2).Column
End With
End If
If AppendData = True Then
Open FName For Append Access Write As #FNum
Else
Open FName For Output Access Write As #FNum
End If
For RowNdx = StartRow To EndRow
WholeLine = ""
For ColNdx = StartCol To EndCol
If Cells(RowNdx, ColNdx).Value = "" Then
CellValue = ""
Else
CellValue = Cells(RowNdx, ColNdx).Value
End If
WholeLine = WholeLine & Chr(34) & CellValue & ".exe" & Chr(34) & "=" & Chr(34) & CellValue & ".exe" & Chr(34) & Sep
Next ColNdx
WholeLine = Left(WholeLine, Len(WholeLine) - Len(Sep))
Print #FNum, WholeLine; ""
Next RowNdx
EndMacro:
On Error GoTo 0
Application.ScreenUpdating = True
Close #FNum
End Sub
Sub PipeExport()
Dim FileName As Variant
Dim Sep As String
FileName = Application.GetSaveAsFilename(InitialFileName:="appList", filefilter:="Text (*.txt),*.txt")
If FileName = False Then
''''''''''''''''''''''''''
' user cancelled, get out
''''''''''''''''''''''''''
Exit Sub
End If
Sep = "|"
If Sep = vbNullString Then
''''''''''''''''''''''''''
' user cancelled, get out
''''''''''''''''''''''''''
Exit Sub
End If
Debug.Print "FileName: " & FileName, "Extension: " & Sep
ExportToTextFile FName:=CStr(FileName), Sep:=CStr(Sep), _
SelectionOnly:=False, AppendData:=False
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
PipeExport
End Sub
The file that is created is appList.txt and its format is the same format as the registry key:
"Acrobat.exe"="Acrobat.exe"
"AcroRd32.exe"="AcroRd32.exe"
Now in your GPO, add a unique program name to the allowed applications list (say test1234.exe) and in your registry editor, go to Edit > Find test1234.exe.
Export that registry key under File > Export. Remove the test1234.exe line and paste in your text file. Then reimport that file and you're done!
I would like to delete 7 days older, files and empty folders. i have used below scripts from the link, but some files and folders are not getting deleted since the souce is pointing directly to drive letter. However, if we change the source folder c:\temp\lab everythings workes fine.
Const Active = True
Const sSource = "E:"
Const MaxAge = 7 'days
Const Recursive = True
Checked = 0
Deleted = 0
Set oFSO = CreateObject("Scripting.FileSystemObject")
if active then verb = "Deleting """ Else verb = "Old file: """
CheckFolder oFSO.GetFolder(sSource)
WScript.echo
if Active then verb = " file(s) deleted" Else verb = " file(s) would be deleted"
WScript.Echo Checked & " file(s) checked, " & Deleted & verb
Sub CheckFolder (oFldr)
For Each oFile In oFldr.Files
Checked = Checked + 1
If DateDiff("D", oFile.DateLastModified, Now()) > MaxAge Then
Deleted = Deleted + 1
WScript.Echo verb & oFile.Path & """"
If Active Then oFile.Delete
End If
Next
if not Recursive then Exit Sub
For Each oSubfolder In oFldr.Subfolders
CheckFolder(oSubfolder)
Next
End Sub
Well, what about this:
Const Active = True
Const sSource = "E:\start_folder" 'or "E:\" but not "E:"
Const MaxAge = 7 'days
Const Recursive = True
Dim dtOld, Checked, Deleted, verb
dtOld = Now - MaxAge
Checked = 0
Deleted = 0
If Active Then verb = "Deleting """ Else verb = "Old file: """
Validate sSource
Cleanup sSource
WScript.Echo
If Active Then verb = " file(s) deleted" Else verb = " file(s) would be deleted"
WScript.Echo Checked & " file(s) checked, " & Deleted & verb
Sub Validate(sFolder)
With CreateObject("Scripting.FileSystemObject")
If Not .FolderExists(sFolder) Then
Err.Raise 76 'Path not found
End If
If .GetFolder(sFolder).IsRootFolder Then
If .GetDrive(.GetDriveName(sFolder)) = _
CreateObject("WScript.Shell").Environment(_
"PROCESS")("HOMEDRIVE") Then
Err.Raise 75 'Path/File access error
End If
End If
End With
End Sub
Sub Cleanup(sFolder)
Dim obj
With CreateObject("Scripting.FileSystemObject").GetFolder(sFolder)
'recurse first
If Recursive Then
For Each obj In .SubFolders
Cleanup obj
Next
End If
'next delete oldest files
For Each obj In .Files
If obj.DateCreated < dtOld Then
Deleted = Deleted + 1
WScript.Echo verb & obj.Path & """"
If Active Then obj.Delete(True)
End If
Next
Checked = Checked + .Files.Count
'and then delete old or empty folders
For Each obj In .SubFolders
If obj.DateCreated < dtOld Or 0 = obj.Size Then
'count here in a variable if you like...
If Active Then obj.Delete(True)
End If
Next
End With
End Sub
P.S. Need to warn about one weak moment. FSO use a snapshot Folders collection, that mean during iteration FSO may try to access folder that no more exists. In other words, made separate procedure for deleting folders.
I am writing a VB Script to update some files on the network. Before beginning, I want to know if any of the files are locked. I'd like to do this before I actually do any updates.
I am aware that I can handle the error if the file is locked when I try to replace it, but I really want to know if any files are locked before I start updating any files.
Is there any way to see that a file is locked using VBS (apart from trying to replace it)?
This function determines whether a file of interest can be accessed in 'write' mode. This is not exactly the same as determining whether a file is locked by a process. Still, you may find that it works for your situation. (At least until something better comes along.)
This function will indicate that 'write' access is not possible when a file is locked by another process. However, it cannot distinguish that condition from other conditions that prevent 'write' access. For instance, 'write' access is also not possible if a file has its read-only bit set or possesses restrictive NTFS permissions. All of these conditions will result in 'permission denied' when a 'write' access attempt is made.
Also note that if a file is locked by another process, the answer returned by this function is reliable only at the moment the function is executed. So, concurrency problems are possible.
An exception is thrown if any of these conditions are found: 'file not found', 'path not found', or 'illegal file name' ('bad file name or number').
Function IsWriteAccessible(sFilePath)
' Strategy: Attempt to open the specified file in 'append' mode.
' Does not appear to change the 'modified' date on the file.
' Works with binary files as well as text files.
' Only 'ForAppending' is needed here. Define these constants
' outside of this function if you need them elsewhere in
' your source file.
Const ForReading = 1, ForWriting = 2, ForAppending = 8
IsWriteAccessible = False
Dim oFso : Set oFso = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
Dim nErr : nErr = 0
Dim sDesc : sDesc = ""
Dim oFile : Set oFile = oFso.OpenTextFile(sFilePath, ForAppending)
If Err.Number = 0 Then
oFile.Close
If Err Then
nErr = Err.Number
sDesc = Err.Description
Else
IsWriteAccessible = True
End if
Else
Select Case Err.Number
Case 70
' Permission denied because:
' - file is open by another process
' - read-only bit is set on file, *or*
' - NTFS Access Control List settings (ACLs) on file
' prevents access
Case Else
' 52 - Bad file name or number
' 53 - File not found
' 76 - Path not found
nErr = Err.Number
sDesc = Err.Description
End Select
End If
' The following two statements are superfluous. The VB6 garbage
' collector will free 'oFile' and 'oFso' when this function completes
' and they go out of scope. See Eric Lippert's article for more:
' http://blogs.msdn.com/b/ericlippert/archive/2004/04/28/when-are-you-required-to-set-objects-to-nothing.aspx
'Set oFile = Nothing
'Set oFso = Nothing
On Error GoTo 0
If nErr Then
Err.Raise nErr, , sDesc
End If
End Function
The script below tries to write to a file for 30 seconds and gives up after that. I needed this when all our users had to click on a script. Chances are that multiple users try to write at the same time. OpenCSV() tries to open the file 30 times with a delay of 1 second in between.
Const ForAppending = 8
currentDate = Year(Now) & "-" & Month(Now) & "-" & Day(Now) & " " & Hour(Now) & ":" & Minute(Now) & ":" & Second(Now)
filepath = "\\network\path\file.csv"
Set oCSV = OpenCSV( filepath )
oCSV.WriteLine( currentDate )
oCSV.Close
Function OpenCSV( path )
Set oFS = CreateObject( "Scripting.FileSystemObject" )
For i = 0 To 30
On Error Resume Next
Set oFile = oFS.OpenTextFile( path, ForAppending, True )
If Not Err.Number = 70 Then
Set OpenCSV = oFile
Exit For
End If
On Error Goto 0
Wscript.Sleep 1000
Next
Set oFS = Nothing
Set oFile = Nothing
If Err.Number = 70 Then
MsgBox "File " & filepath & " is locked and timeout was exceeded.", vbCritical
WScript.Quit
End If
End Function
Or, more simply:
Assuming you already have a variable in your VBS named FileName, which contains the full filepath you want to test:
Dim oFso, oFile
Set oFso = CreateObject("Scripting.FileSystemObject")
Set oFile = oFso.OpenTextFile(FileName, 8, True)
If Err.Number = 0 Then oFile.Close
Line 3 tries to open the file you want to test with append permissions enabled. e.g. it attempts to open the file with a write lock.
If opening the file with a write lock generates an error, then your VBS will error on the third line and not continue. At that point your error handling from wherever you called the VBS should kick in. The error message will be "Permission Denied" if you couldn't get a write lock.
If opening the file with a lock doesn't result in an error, then line 4 closes it again. You can now open the file or do whatever you want with it, confident that it doesn't have a write lock on it.
When extracting files from a ZIP file I was using the following.
Sub Unzip(strFile)
' This routine unzips a file. NOTE: The files are extracted to a folder '
' in the same location using the name of the file minus the extension. '
' EX. C:\Test.zip will be extracted to C:\Test '
'strFile (String) = Full path and filename of the file to be unzipped. '
Dim arrFile
arrFile = Split(strFile, ".")
Set fso = CreateObject("Scripting.FileSystemObject")
fso.CreateFolder(arrFile(0) & "\ ")
pathToZipFile= arrFile(0) & ".zip"
extractTo= arrFile(0) & "\ "
set objShell = CreateObject("Shell.Application")
set filesInzip=objShell.NameSpace(pathToZipFile).items
objShell.NameSpace(extractTo).CopyHere(filesInzip)
fso.DeleteFile pathToZipFile, True
Set fso = Nothing
Set objShell = Nothing
End Sub 'Unzip
This was working, but now I get a "The File Exists" Error.
What is the reason for this? Are there any alternatives?
All above solutions are accurate, but they are not definitive.
If you are trying to extract a zipped file into a temporary folder, a folder that displays "Temporary Folder For YOURFILE.zip" will immediately be created (in C:\Documents and Settings\USERNAME\Local Settings\Temp) for EACH FILE contained within your ZIP file, which you are trying to extract.
That's right, if you have 50 files, it will create 50 folders within your temp directory.
But if you have 200 files, it will stop at 99 and crash stating - The File Exists.
..
Apparently, this does not occur on Windows 7 with the contributions I view above. But regardless, we can still have checks. Alright, so this is how you fix it:
'========================
'Sub: UnzipFiles
'Language: vbscript
'Usage: UnzipFiles("C:\dir", "extract.zip")
'Definition: UnzipFiles([Directory where zip is located & where files will be extracted], [zip file name])
'========================
Sub UnzipFiles(folder, file)
Dim sa, filesInzip, zfile, fso, i : i = 1
Set sa = CreateObject("Shell.Application")
Set filesInzip=sa.NameSpace(folder&file).items
For Each zfile In filesInzip
If Not fso.FileExists(folder & zfile) Then
sa.NameSpace(folder).CopyHere(zfile), &H100
i = i + 1
End If
If i = 99 Then
zCleanup(file, i)
i = 1
End If
Next
If i > 1 Then
zCleanup(file, i)
End If
fso.DeleteFile(folder&file)
End Sub
'========================
'Sub: zCleanup
'Language: vbscript
'Usage: zCleanup("filename.zip", 4)
'Definition: zCleanup([Filename of Zip previously extracted], [Number of files within zip container])
'========================
Sub zCleanUp(file, count)
'Clean up
Dim i, fso
Set fso = CreateObject("Scripting.FileSystemObject")
For i = 1 To count
If fso.FolderExists(fso.GetSpecialFolder(2) & "\Temporary Directory " & i & " for " & file) = True Then
text = fso.DeleteFolder(fso.GetSpecialFolder(2) & "\Temporary Directory " & i & " for " & file, True)
Else
Exit For
End If
Next
End Sub
And that's it, copy and paste those two functions into your VBScript hosted program and you should be good to go, on Windows XP & Windows 7.
Thanks!
You can use DotNetZip from VBScript.
To unpack an existing zipfile, overwriting any files that may exist:
WScript.echo("Instantiating a ZipFile object...")
Dim zip
Set zip = CreateObject("Ionic.Zip.ZipFile")
WScript.echo("Initialize (Read)...")
zip.Initialize("C:\Temp\ZipFile-created-from-VBScript.zip")
WScript.echo("setting the password for extraction...")
zip.Password = "This is the Password."
' set the default action for extracting an existing file
' 0 = throw exception
' 1 = overwrite silently
' 2 = don't overwrite (silently)
' 3 = invoke the ExtractProgress event
zip.ExtractExistingFile = 1
WScript.echo("extracting all files...")
Call zip.ExtractAll("extract")
WScript.echo("Disposing...")
zip.Dispose()
WScript.echo("Done.")
To create a new zipfile:
dim filename
filename = "C:\temp\ZipFile-created-from-VBScript.zip"
WScript.echo("Instantiating a ZipFile object...")
dim zip2
set zip2 = CreateObject("Ionic.Zip.ZipFile")
WScript.echo("using AES256 encryption...")
zip2.Encryption = 3
WScript.echo("setting the password...")
zip2.Password = "This is the Password."
WScript.echo("adding a selection of files...")
zip2.AddSelectedFiles("*.js")
zip2.AddSelectedFiles("*.vbs")
WScript.echo("setting the save name...")
zip2.Name = filename
WScript.echo("Saving...")
zip2.Save()
WScript.echo("Disposing...")
zip2.Dispose()
WScript.echo("Done.")
There's answers above which are perfectly correct, but I thought I'd wrap everything up into a full solution that I'm using:
strZipFile = "test.zip" 'name of zip file
outFolder = "." 'destination folder of unzipped files (must exist)
'If using full paths rather than relative to the script, comment the next line
pwd = Replace(WScript.ScriptFullName, WScript.ScriptName, "")
Set objShell = CreateObject( "Shell.Application" )
Set objSource = objShell.NameSpace(pwd+strZipFile).Items()
Set objTarget = objShell.NameSpace(pwd+outFolder)
intOptions = 256
objTarget.CopyHere objSource, intOptions
'Clean up
Set WshShell = CreateObject("Wscript.Shell")
tempfolder = WshShell.ExpandEnvironmentStrings("%temp%")
Set fso = CreateObject("Scripting.FileSystemObject")
Call fso.DeleteFolder(tempfolder + "\Temporary Directory 1 for " + strZipFile, True )
http://www.experts-exchange.com/Programming/Languages/Visual_Basic/VB_Script/Q_23022290.html
Check your temp directory. If you have 99 folders associated with this unzipping process, try deleting them.
I added the following code to the beginning of my unzip procedure to delete these directories before I unzip:
For i = 1 To 99
If aqFileSystem.Exists(GetAppPath("Local Settings", "") & "\Temp\Temporary Directory " & i & " for DialogState.zip") = True Then
result = aqFileSystem.ChangeAttributes(GetAppPath("Local Settings", "") & "\Temp\Temporary Directory " & i & " for DialogState.zip", 1 OR 2, aqFileSystem.fattrFree)
Call DelFolder(GetAppPath("Local Settings", "") & "\Temp\Temporary Directory " & i & " for DialogState.zip")
Else
Exit For
End If
Next