Showing posts with label powershell. Show all posts
Showing posts with label powershell. Show all posts

Wednesday, September 22, 2021

Execute PowerShell in Windows Scheduled Task

 There are many ways to execute PowerShell in Windows scheduled tasks:

Option #1

Program/Script: PowerShell.exe

Add arguments (optional): -command "& {& 'C:\path\to\script.ps1'}"

Start in (optional): C:\path\to\

Option #2

Program/Script: PowerShell.exe

Add arguments (optional): -NonInteractive -Noprofile -File "C:\path\to\script.ps1"

Start in (optional): C:\path\to\

Option #1 allows me to have the script to connect to the Internet (server is located behind corporate proxy). 

Friday, June 12, 2020

Hyper-V Nested VM

To allow your VM to run Hyper-V role, you need to expose the virtualization extension to the Hyper-V host by running the following PowerShell command:

> Set-VMProcessor -VMname MyVM -ExposeVirtualizationExtensions $true

Wednesday, January 08, 2020

PowerShell and Excel

I wrote a PowerShell script to start MS Excel process and manipulate an Excel file. This PS works perfectly fine when it is executed interactively by a user account. However when using Windows task scheduler, it throws the following errors:

Microsoft Excel cannot access the file
There are several possible reasons:
The file name or path does not exist.
The file is being used by another program.
The workbook you are trying to save has the same name as a currently open workbook.

In turns out, I need to create a directory named: Desktop
In the following locations:

64-Bit OS
C:\Windows\SysWOW64\config\systemprofile\Desktop

32-Bit OS
C:\Windows\System32\config\systemprofile\Desktop

Friday, November 22, 2019

Tail in PowerShell

 I need to "tail" in PowerShell to view the log and found the following command interesting:

> Get-Content C:\mylog.txt -Wait

If you want to get the latest file and tail it:

> Get-Content ( Get-ChildItem C:\Folder\ | Sort-Object LastWriteTime | Select-Object -Last 1) -Wait

Thursday, September 12, 2019

Active Directory Group Policy by Powershell

 Use the following Powershell to get all the GPO dumped to HTML files

#> Get-GPO -All -Domain mydomain.tld | % { Get-GPOReport -Guid $_.Id -ReportType Html -Domain mydomain.tld | Set-Content C:\Reports\$($_.DisplayName).html }

Tuesday, January 01, 2019

Windows Server Core 2019 - Remote PowerShell

Just installed a couple of Windows Server Core 2019. To manage them through PowerShell remotely, you need to enable PowerShell Remoting

On the Windows Server 2019 Core, run the following command

> Enable-PSRemoting -Force

The remote machine from which you want to manage the server

> Enter-PSSession -Credential (Get-Credential) -ComputerName my2019server.domain.tld

Enjoy!

Thursday, April 19, 2018

PowerShell RunAs

To execute PowerShell to Run As a different credential:

> $cred = Get-Credential
> Start-Process powershell.exe -Credential $cred -NoNewWindow -ArgumentList "-noprofile -command &{Start-Process -FilePath C:\blah\prog.exe}"

Friday, March 16, 2018

PowerShell SecureString

PowerShell is often used to access data from systems or apps that require authentication. Authentication requires username and password. you don't want to store the password in the PowerShell script itself.

The better way is to store the password as SecureString in a configuration file and use that to access the data / app.

To generate the configuration file:

Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File C:\Securestring.txt

To consume the configuration file:

> $pass = Get-Content C:\Securestring.txt | ConvertTo-SecureString

To convert it as credential object:

$cred= New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "username",$pass

Wednesday, October 26, 2016

Windows 2012 R2 - File Backup

I need to backup my files running on Windows 2012 R2 to external drive. I also need this to be done in a regular basis and send me an email after the job done with the report.

First, I create a batch file, called backup.bat, with the content

@echo off
robocopy H:\Home V:\Home /MIR /R:1 /W:1 /LOG:V:\Home.txt
robocopy K:\Documents V:\Documents /MIR /R:1 /W:1 /LOG:V:\Documents.txt
copy /b V:\Documents.txt +V:\Home.txt V:\Backup.txt

The last line is joining the 2 log files into a single file, backup.txt

Schedule this daily with the Windows Scheduler, having an actions:

Start a Program: cmd.exe
Add arguments: /c D:\scripts\backup.bat

That bit is done for backup job.

Now, the email bit. I create a powershell script, called email.ps1, with the content:

 function sendMail{

     Write-Host "Sending Email"

     #SMTP server name
     $smtpServer = "smtprelay.domain.local"

     #Creating a Mail object
     $msg = new-object Net.Mail.MailMessage

     #Creating SMTP server object
     $smtp = new-object Net.Mail.SmtpClient($smtpServer)

     #Email structure 
     $msg.From = "backup@mydomain.id.au"
     $msg.ReplyTo = "backup@mydomain.id.au"
     $msg.To.Add("me@mydomain.id.au")
     $msg.subject = "Backup Email - Daily"
     $msg.body = "Backup Email - Daily"
     $attachment = New-Object System.Net.Mail.Attachment("V:\Backup.txt", 'text/plain')
     $msg.Attachments.Add($attachment)

     #Sending email 
     $smtp.Send($msg)
  
}

#Calling function

sendMail 

The email powershell script attach the backup.txt file and send it away
On the same schedule job created earlier, add a second action:

Start a Program: powershell
Add arguments: D:\scripts\email.ps1

Done. Second action will be executed after the 1st action is running and it will grab the log and attach it to the email.

Monday, May 16, 2016

PowerShell - Mount BitLocker Encrypted VHD

If you have .VHD BitLocker encrypted files and would like to mount it using PowerShell:

$ss = Read-Host "Enter BitLocker Password:" -AsSecureString

Mount-VHD <path-to-VHD>\Example.VHD

#Check your disk manager which drive letter the volume is assigned to the VHD

Unlock-BitLocker -MountPoint <drive letter> -Password $ss


Tuesday, May 12, 2015

PowerShell List Volumes

Just a quick PowerShell to get the list of volumes on your server

Get-wmiobject Win32_volume | Select Name, @{n="Capacity (GB)";e={$_.Capacity/1GB}},@{n="Freespace (GB)";e={$_.Freespace/1GB}}

Saturday, October 25, 2014

Getting AD NetBIOS Name From User DN

(Get-ADDomain (($user.DistinguishedName.Split(",") | ? {$_ -like "DC=*"}) -join ",")).NetBIOSName

Sunday, August 31, 2014

PowerShell Sorting Hash Table

This is just a quick one, how to sort PowerShell Hash Table:

$ht = @{}
$ht.Add(key1,value1)
$ht.Add(key2,value2)

$ht = $ht.GetEnumerator() | Sort-Object -Descending Value

Wednesday, July 16, 2014

PowerShell Module Quick Rundown

Yes, you have created PowerShell Script. But you better off converting your PowerShell script to a PowerShell Module.

To create a module, first you need to convert your script to a function. Test the function and when you are ready:

(optional) - Export Function to be exposed to the public
add the following line to the end of your PowerShell Script File
Export-ModuleMember -Function <Function Name>

Save the file as <ModuleName>.psm1
Note: <ModuleName> is the module name

Get the PS Module path
$env:PSModulePath

Go to the PS Module Path
Create a folder EXACTLY the same name with <ModuleName>
Store the <ModuleName>.psm1 to the PS Module Path folder created

Check the Module is now available
Get-Module -ListAvailable

Import Module
Import-Module <ModuleName>

To view command available in the module
Get-Command -Module <ModuleName>

(optional) - To Create Manifest
New-ModuleManifest -Path <Path to the .psd1 new manifest file> -FunctionsToExport <Name of functions to be exported> -Author <Author Name> -CompanyName <Company> - Copyright <Copyright> -ModuleVersion <version#> -Description <Module Description>

Note: Path must be the same location where the actual module file (.psm1) is located

Friday, November 29, 2013

PowerShell Awesomeness!!

Loves PowerShell!

Here is how to get the details of all mailboxes in Exchange 2013 and then assign it to the new App of Enterprise Vault 10.0.4 in a particular OU:


Get-ADUser -SearchBase "OU=My Users,DC=domain,DC=local" -SearchScope Subtree -Filter {proxyaddresses -like "smtp:*"} | ForEach-Object {$mbx = Get-Mailbox $_.SamAccountName; New-App -mailbox $mbx.LegacyExchangeDN -Url ("https://vault.domain.local/EnterpriseVault/OfficeMailAppManifest.aspx?LegacyMbxDn=" + $mbx.LegacyExchangeDN + "&BaseURL=https://vault.domain.com/EnterpriseVault")}


Don't forget the change the -SearchBase, -Url parameters.

All the users in the OU with mailbox enabled will get the new Enterprise Vault Web Application!

Tuesday, December 11, 2012

DNS IP to localhost

While I am doing this coding of DNS server and using my development machine to debug the program, I need to somehow configure my Windows 7 client's DNS setting to point to itself as the DNS server (e.g. 127.0.0.1).

Surprisingly, Windows 7 rejects the setting when you put 127.0.0.1 as the DNS IP address of your network connection.

Found the following Powershell to change it easily

$wmi = Get-WmiObject win32_networkadapterconfiguration -filter "ipenabled = 'true'"
$wmi.SetDNSServerSearchOrder("127.0.0.1")

Friday, June 15, 2012

Exchange 2010 Distribution List Owner

I have been migrating user mailboxes from Exchange 2007 to Exchange 2010 lately. Apparently a user who has got the manage rights to a distribution list in Exchange 2007, might not be able to manage their DL anymore once his/her mailbox has been migrated to the Exchange 2010.

This is by design. Exchange 2010 by default does not allow individual users to create, modify, remove and add members to distribution groups they own


The user will get access denied if they were trying to add/remove a user from the DL they were managing. To fix this, you can tick the check box from the RBAC User Editor/Default Role Assignment Policy. However as you can see in the description of this option, it will also grant the user to add and delete the DL by them self.

If we were only want to enable them to only manage the DL their own, you need to use the following PowerShell script:

# Script for creating a Role that can manage distributions groups but can't create new ones 
#  
################################################################################# 
#  
# The sample scripts are not supported under any Microsoft standard support  
# program or service. The sample scripts are provided AS IS without warranty  
# of any kind. Microsoft further disclaims all implied warranties including, without  
# limitation, any implied warranties of merchantability or of fitness for a particular  
# purpose. The entire risk arising out of the use or performance of the sample scripts  
# and documentation remains with you. In no event shall Microsoft, its authors, or  
# anyone else involved in the creation, production, or delivery of the scripts be liable  
# for any damages whatsoever (including, without limitation, damages for loss of business  
# profits, business interruption, loss of business information, or other pecuniary loss)  
# arising out of the use of or inability to use the sample scripts or documentation,  
# even if Microsoft has been advised of the possibility of such damages 
# 
################################################################################# 
# 
# Written by Matthew Byrd 
# Matbyrd@microsoft.com 
# Last Updated 10.15.09 
 
 
# Parameter to get a different name than default for the new Role 
Param([string]$name="MyDistributionGroupsManagement",[string]$policy="Default Role Assignment Policy",[switch]$creategroup,[switch]$removegroup) 
 
# Help Function 
Function Show-Help { 
 
" 
This script is will create or manage a management role designed to allow users to modify groups that they already own 
but not create or remove any new distribution groups. 
 
Switches: 
-name           Name of the managment role you want to create or modify 
                    Defaults to: `"MyDistributionGroupsManagmenet`" 
                     
-policy         Name of the Role Policy you want to assign the role to 
                    Defaults to: `"Default Role Assignement Policy`" 
                     
-creategroup    Adds or Removes the ability of the Role to Create DLs 
 
-removegroup    Adds or Removes the ability of the Role to Remove DLs 
 
Examples: 
-------------------------------------------- 
This will Use the default names and Policy and will create a role that cannot 
Create or remove groups but can still modify them.  If the role already exists 
It will modify it by removing or adding the abiltity to create and remove groups 
based on the current state. 
 
Manage-GroupManagementRole -CreateGroup -RemoveGroup 
 
" 
 
 
} 
 
 
 
# Function to modify a role by removing or adding Role Entries 
# If no action is passed we assume remove 
# $roleentry should be in the form Role\Roleentry e.g. MyRole\New-DistributionGroup 
Function ModifyRole { 
 Param($roleenty,$action) 
     
    Switch ($action){ 
        Add {Add-ManagementRoleEntry $roleenty -confirm:$false} 
        Remove {Remove-ManagementRoleEntry $roleenty -confirm:$false} 
        Default {Remove-ManagementRoleEntry $roleenty -confirm:$false} 
    } 
} 
 
If (($creategroup -eq $false) -and ($removegroup -eq $false)){ 
    Show-Help 
    exit 
} 
 
 
# Test if we have a role that already has that name 
If (([bool](Get-Managementrole $name -erroraction Silentlycontinue)) -eq $true){ 
    Write-Warning "Found a Role with Name: $name" 
    Write-Warning "Trying to Modify Existing Role" 
} 
Else { 
    # Create the new Management Role 
    Write-Host "Creating Managmenet Role $name" 
    New-ManagementRole -name $name -parent MyDistributionGroups 
} 
 
# Determine if we have the New and Remove Role Entries on the Role Already 
$create = [bool](Get-managementroleentry $name\New-DistributionGroup -erroraction Silentlycontinue) 
$remove = [bool](Get-managementroleentry $name\Remove-DistributionGroup -erroraction Silentlycontinue) 
 
# If we have the switch CreateGroup add or remove the RoleEntry for New-DistributionGroup 
If ($creategroup -eq $true){ 
    If ($create -eq $true){ModifyRole $name\New-DistributionGroup Remove;Write-Host "Removing ability to create distribution Groups from $name"} 
    elseif ($create -eq $false) {ModifyRole $name\New-DistributionGroup Add;Write-Host "Adding ability to create distribution Groups to $name"} 
} 
 
# If we have the switch RemoveGroup add or remove the RoleEntry for New-DistributionGroup 
If ($removegroup -eq $true){ 
    If ($remove -eq $true){ModifyRole $name\Remove-DistributionGroup Remove;Write-Host "Removing ability to create distribution Groups from $name"} 
    elseif ($remove -eq $false) {ModifyRole $name\Remove-DistributionGroup Add;Write-Host "Adding ability to create distribution Groups to $name"} 
} 
 
# Test if we have the assignment for the Role and Policy 
# If we do ... write a warning 
# If not create a new assignment 
If (([bool](get-managementroleassignment $name-$policy -erroraction SilentlyContinue)) -eq $true){ 
    Write-Warning "Found Existing Role Assignment: $name-$policy" 
    Write-Warning "Making no modifications to Role Assignments" 
} 
Else { 
    # Assign the Role to the Role Policy 
    Write-Host "Creating Managmenet Role Assignment $name-$policy" 
    New-ManagementRoleAssignment -name ($name + "-" + $policy) -role $name -policy $policy 
} 

Save the code to as MyDistributionGroupsManagement.ps1 file
Run the script:

MyDistributionGroupsManagement.ps1 -creategroup -removegroup

The script is basically create another role as a child role of the MyDistributionGroups and remove the ability to create and remove DL.
Once you have run the script, you will have the following Role:


Thanks to MS Exchange Team to share the script here

Monday, July 04, 2011

PowerShell AD Group Membership Listing

To get the member of a particular group in Active Directory:

Get-ADGroup -filter 'name -eq "Group Name" | Get-ADGroupMember -Recursive | fl name

Replace the "Group Name" with the group name from which you want to get the member of

Friday, April 23, 2010

Symantec Enterprise Vault

The following is a modified PowerShell script from Symantec to recall all the files from Vault if the file placeholder exist in the file server

## script attempt - comprehensive FSA script to analyze target locations and evaluate file within it
##
## First we check the registry to see if the bypassrecallimitsforadmins key (8.0) or bypassrecalllimitsforadmins (7.5 something where it was spelt right)
## We also check recalllimitmaxrecalls and recalllimittimeinterval to see if they are set to 99 and 1 respectively to give the best chance to recall all files if needed
## Note: while they may not choose to copy we will still get these values for later processing in case they do
##
## We will prompt for 2 locations: 1) the location of the fatr.exe executable & batch.cmd, and 2) the desired target path
## We will prompt for a decision if the user wants the placeholders that are verified as proper placeholders would also like them recalled (by copy to nul process)
## If they choose the copy option, we will report on the registry settings and recommend changes (and do them if they choose).
## Using these paths we will do the following
## 1) get a directory output of the target path and save that to a file named dirout.txt
## 2) using the dirout.txt file we will process each file in that list in the following manner
## 3) we will run fsutil (windows application) to confirm if the file has reparsepoint (placeholder) information, and if so, if the GUID matches the EV one (because of some issues found on 64 bit, this string has had the spaces removed to ensure matches on 64 and non-64 bit systems)
## *4) we will test the file as well with the fatr.exe application (in report mode) which will detail to us if the offline file bit is set or not
## 5) if the above tests result in finding a file which has the offline bit set, and NO reparse information, we will set the offline bit OFF (this will resolve the 'element not found errors' on archive attempts)
## 6) if the above tests result in finding a file which has the offline bit set, and EV reparse information, we will leave the file alone if copy choice is 'n' or copy the item to nul if 'y'
## 7) if the above tests result in finding a file which has the offline bit set, and reparse information (but not EV info), we will leave the file alone
## 8) if the above tests result in finding a file which has the offline bit unset, and NO reparse information, we will leave the file alone
## 9) if the above tests result in finding a file which has the offline bit unset, and EV reparse information, we will set the offline bit (this situation should not be found)
## 10) if the above tests result in finding a file which has the offline bit unset, and reparse information (but not EV info), we will leave the file alone
## 11) if the above tests result in finding not covered by the above we will report the results found and do nothing

##param

## ver.bat ($exepath = "$(read-host "Please enter the path to the fatr.exe & batch.cmd files. Use the format, :\, e.g. c:\testfolder ")",$tarpath = "$(read-host "Please enter the path to the desired target folder to analyze. Use the format, :\, e.g. c:\testfolder ")",$copyquestion = "$(read-host "If proper placeholders are found, would you like them recalled? Use the format y or n")")
$tarpath = $(read-host "Please enter the path to the desired target folder to analyze. Use the format, :\, e.g. c:\testfolder ")
$copyquestion = $(read-host "If proper placeholders are found, would you like them recalled? Use the format y or n")

## ------------------------------------------------
## Edited by Me (u know)
## ------------------------------------------------

$txtfile = $(read-host "Please enter the path to the file to search target. Use the format, :\\filename, e.g. c:\testfolder\file.txt")

## ------------------------------------------------

## $outpath = "$(read-host "Please enter the path for the output file. Use the format, :\, e.g. c:\testfolder ")" ## we should not need this line as output will be specified at run time.

$restart = 0
$script = $myinvocation.mycommand.definition
$exepath = split-path "$script"

##debug ##write-host $exepath
##debug ##write-host $tarpath
##debug ## write-host $tarpath

Write-Output "++++++++++++++++++++++++++++++++++" > $exepath\test1.txt
Write-Output "" >> $exepath\test1.txt
get-date out-file -filepath $exepath\test1.txt -append
Write-Output "Processing Started" >> $exepath\test1.txt
Write-Output "" >> $exepath\test1.txt


If ($copyquestion -eq 'y'){
Write-Output "Copy operation selected checking registry" >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
$bol = test-path -path "HKLM:\SOFTWARE\Wow6432Node\KVS\Enterprise Vault\FSA\PlaceholderService"
$bol2 = test-path -path "HKLM:\SOFTWARE\KVS\Enterprise Vault\FSA\PlaceholderService"

If ($bol){
## 64 bit PHS
$testreg = get-itemproperty "HKLM:\SOFTWARE\Wow6432Node\KVS\Enterprise Vault\FSA\PlaceholderService"

If ($testreg.BypassRecalLimitsForAdmins -eq 1){
write-host "BypassRecalLimitsForAdmins is set (64 bit)"
write-output "BypassRecalLimitsForAdmins is set (64 bit)" >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
}
Else{
$bypassnotset =$(read-host "The registry setting, BypassRecalLimitsForAdmins is not set, would you like to set it? Use the format y or n ")

If ($bypassnoteset = 'y'){
write-host "Setting BypassRecalLimitsForAdmins to 1"
write-output "Setting BypassRecalLimitsForAdmins to 1"
write-output "" >> $exepath\test1.txt
set-itemproperty -path "HKLM:\SOFTWARE\Wow6432Node\KVS\Enterprise Vault\FSA\PlaceholderService" -name "BypassRecalLimitsForAdmins" -value 1
$restart = 1
}
Else{
write-host "Not setting BypassRecalLimitsForAdmins can cause recall processing to fail if recall limits are encountered. Will exit. "
Break
}
}

If ($testreg.RecallLimitMaxRecalls -eq 99){
write-host "RecallLimitMaxrecalls is set to the highest accepted value (99) "
write-output "RecallLimitMaxrecalls is set to the highest accepted value (99) " >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
}
Else{
write-host "RecallLimitMaxrecalls is NOT set to the highest accepted value (99) "
$recalllimitnotset =$(read-host "The registry setting, RecallLimitMaxrecalls is not set to the highest acceptable value, would you like to set it? Use the format y or n ")

If ($recalllimitnotset = 'y'){
write-host "Setting RecallLimitMaxrecalls to 99"
write-output "Setting RecallLimitMaxrecalls to 99" >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
set-itemproperty -path "HKLM:\SOFTWARE\Wow6432Node\KVS\Enterprise Vault\FSA\PlaceholderService" -name "RecallLimitMaxrecalls" -value 99
$restart = 1
}
Else{
write-host "Not setting RecallLimitMaxrecalls can cause recall processing to fail if recall limits are encountered. Will exit. "
Break
}
}

If ($testreg.RecallLimitTimeInterval -eq 1){
write-host "RecallLimitTimeInterval is set to the lowest accepted value (1) "
write-output "RecallLimitTimeInterval is set to the lowest accepted value (1) " >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
}
Else{
$recalllimitTnotset =$(read-host "The registry setting, RecallLimitTimeInterval is not set to the lowest acceptable value, would you like to set it? Use the format y or n ")

If ($recalllimitTnotset = 'y'){
write-host "Setting RecallLimitTimeInterval to 1"
write-output "Setting RecallLimitTimeInterval to 1" >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
set-itemproperty -path "HKLM:\SOFTWARE\Wow6432Node\KVS\Enterprise Vault\FSA\PlaceholderService" -name "RecallLimitTimeInterval" -value 1
$restart = 1
}
Else{
write-host "Not setting RecallLimitTimeInterval can cause recall processing to fail if recall limits are encountered. Will exit. "
Break
}
}
}
ElseIf ($bol2){
## 32 bit PHS
$testreg = get-itemproperty "HKLM:\SOFTWARE\KVS\Enterprise Vault\FSA\PlaceholderService"
$eval1 = $testreg.BypassRecalLimitsForAdmins

## debug ##
write-host $eval1
If ($eval1 -eq 1){
write-host "BypassRecalLimitsForAdmins is set"
write-output "BypassRecalLimitsForAdmins is set" >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
}
Else{
$bypassnotset =$(read-host "The registry setting, BypassRecalLimitsForAdmins is not set, would you like to set it? Use the format y or n ")

If ($bypassnoteset = 'y'){
write-host "Setting BypassRecalLimitsForAdmins to 1"
write-output "Setting BypassRecalLimitsForAdmins to 1" >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
set-itemproperty -path "HKLM:\SOFTWARE\KVS\Enterprise Vault\FSA\PlaceholderService" -name "BypassRecalLimitsForAdmins" -value 1
$restart = 1
}
Else{
write-host "Not setting BypassRecalLimitsForAdmins can cause recall processing to fail if recall limits are encountered. Will exit. "
Break
}
}

If ($testreg.RecallLimitMaxRecalls -eq 99){
write-host "RecallLimitMaxrecalls is set to the highest accepted value (99) "
write-output "RecallLimitMaxrecalls is set to the highest accepted value (99) " >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
}
Else{
#write-host "RecallLimitMaxrecalls is NOT set to the highest accepted value (99) "
write-output "RecallLimitMaxrecalls is NOT set to the highest accepted value (99) " >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
$recalllimitnotset =$(read-host "The registry setting, RecallLimitMaxrecalls is not set to the highest acceptable value, would you like to set it? Use the format y or n ")

If ($recalllimitnotset -eq 'y'){
write-host "Setting RecallLimitMaxrecalls to 99"
write-output "Setting RecallLimitMaxrecalls to 99" >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
set-itemproperty -path "HKLM:\SOFTWARE\KVS\Enterprise Vault\FSA\PlaceholderService" -name "RecallLimitMaxrecalls" -value 99
$restart = 1
}
Else{
write-host "Not setting RecallLimitMaxrecalls can cause recall processing to fail if recall limits are encountered. Will exit. "
Break
}
}

If ($testreg.RecallLimitTimeInterval -eq 1){
write-host "RecallLimitTimeInterval is set to the lowest accepted value (1) "
write-output "RecallLimitTimeInterval is set to the lowest accepted value (1) " >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
}
Else{
$recalllimitTnotset =$(read-host "The registry setting, RecallLimitTimeInterval is not set to the lowest acceptable value, would you like to set it? Use the format y or n ")

If ($recalllimitTnotset -eq 'y'){
write-host "Setting RecallLimitTimeInterval to 1"
write-output "Setting RecallLimitTimeInterval to 1" >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
set-itemproperty -path "HKLM:\SOFTWARE\KVS\Enterprise Vault\FSA\PlaceholderService" -name "RecallLimitTimeInterval" -value 1
$restart = 1
}
Else{
write-host "Not setting RecallLimitTimeInterval can cause recall processing to fail if recall limits are encountered. Will exit. "
Break
}
}
}
Else{
write-output "Registry Read failed for path HKLM:\SOFTWARE\Wow6432Node\KVS\Enterprise Vault\FSA\PlaceholderService and HKLM:\SOFTWARE\KVS\Enterprise Vault\FSA\PlaceholderService Copy operations may be limited by recall limits "
}
}
Else{
write-host "Copy not selected "
write-output "Copy not selected " >> $exepath\test1.txt
}

if ($restart -gt 0){
restart-service "Enterprise Vault File Placeholder Service"
write-host "Restarting EV File Placeholder Service"
write-output "Restarting EV File Placeholder Service" >> $exepath\test1.txt
write-output "" >> $exepath\test1.txt
}

## ver.bat & $exepath"\batch.cmd" $tarpath > $exepath"\dirout.txt"

## & $exepath"\batch.cmd" $tarpath > $exepath"\dirout.txt"
## above worked at the command line in PS

## ver.bat $readlines = get-content $exepath\dirout.txt
##$readlines = get-childitem $tarpath -force -recurse where-object {$_.mode -notlike "d*"}

## ------------------------------------------------
## Edited by Me (u know)
## ------------------------------------------------

Get-Content $txtfile Foreach-Object {
$searchstring = $_
$searchbase = "$tarpath\$searchstring*"

write-host $searchbase
write-output "Searching folder beginning with $searchstring ..." >> "$exepath\$searchstring.txt"

## $readlines = get-childitem $searchbase -force -recurse where-object {$_.mode -notlike "d*" -and $_.length -lt 10000}

$readlines = get-childitem $searchbase -force -recurse -exclude *.ldb where-object {$_.mode -notlike "d*"}
#$readlines = get-childitem -LiteralPath "F:\Groups\Development\Developments - Commercial\Administration Stationary\VIC\GeneralAdmin\Expenses_04_05\051209memo[Expenses-Richard].doc"


## ------------------------------------------------

##
##
## $count = 0
foreach($readline in $readlines){
$fullname = $readline.fullname
$fsutilout = fsutil reparsepoint query "$fullname"
## pass fsutilout to new variable to ensure string
$fsutiloutst = "$fsutilout"
## debug ## write-host "running fsutil on file " $fullname " returned " $fsutiloutst

$filetest = Get-ChildItem -LiteralPath "$fullname" -Force

#trap{
# $filetest = Get-ChildItem -LiteralPath "$fullname" -Force
# "ERROR Filetest: file $filetest :: "+ $_ out-file "$exepath\$searchstring error.txt" -append
# write-host $_
# continue
#}

#$filetest = $fullname

$offline = $filetest.Attributes -band [System.IO.FileAttributes]::Offline

trap{
"ERROR->file $filetest :: "+ $_ out-file "$exepath\$searchstring error.txt" -append
write-host $_
continue
}

###$fatrout = & $exepath"\fatr.exe" -r "$fullname"
## next pass $fatrout to another variable to properly get it in a string
###$fatroutst = "$fatrout"
## debug ## write-host "running fatr in report mode on file " $fullname " returned " $fatroutst

## Logic for evaluation of the strings

## new test for offline - Determining if an attribute is set
## $File = Get-ChildItem .\test.txt -Force
## $File.Attributes
## if ( $File.Attributes -band [System.IO.FileAttributes]::Hidden )
## { Write-Host "Hidden Attribute Set" }

## Setting an attribute

## $File = Get-ChildItem .\test.txt -Force
## $File.Attributes
## $File.Attributes = ( $File.Attributes -bor [System.IO.FileAttributes]::System )
## $File.Attributes

## Removing an attribute
## $File = Get-ChildItem .\test.txt -Force
## $File.Attributes
## $File.Attributes = ( $File.Attributes -bxor [System.IO.FileAttributes]::System )
## $File.Attributes


If ($fsutiloutst -match'(?m:^Error)' -and $offline -eq 0){
$out1 = "The file "+$fullname+" has no EV reparse information and does not have the offline bit set, no action needed"
out-file -filepath "$exepath\$searchstring.txt" -inputobject $out1 -append

}
elseif ($fsutiloutst -replace ' ', '' -match '(^ReparseTagValue:0x00000010GUID:{9DD58ACD-4BE7-4F36-9CE3-B7738EE3C702})' -and $offline -eq 0){
$out2 = "The file "+$fullname+" has EV reparse information and does not have the offline bit set, will set offline bit"
out-file -filepath "$exepath\$searchstring.txt" -inputobject $out2 -append
$filetest.Attributes = $filetest.Attributes -bor [System.IO.FileAttributes]::Offline
# & $exepath"\fatr.exe" $fullname >> $exepath\test1.txt
}
elseif ($fsutiloutst -match'(?m:^Error)' -and $offline -eq 4096){
$out3 = "The file "+$fullname+" has no EV reparse information and does have the offline bit set, will clear offline bit"
out-file -filepath "$exepath\$searchstring.txt" -inputobject $out3 -append
$filetest.Attributes = $filetest.Attributes -bxor [System.IO.FileAttributes]::Offline
# & $exepath"\fatr.exe" $fullname >> $exepath\test1.txt
}
else{
## only case left should be has reparse, and has offline bit set
# $fullname
If ($copyquestion -match 'y'){
$out4 = "The file "+$fullname+" has EV reparse information, and is offline, will attempt to copy to nul device as copy selection set to 'y'"
out-file -filepath "$exepath\$searchstring.txt" -inputobject $out4 -append

#trap{
# "The File: "+ $fullname out-file "$exepath\$searchstring error.txt" -append
# "ERROR: "+ $_ out-file "$exepath\$searchstring error.txt" -append
# write-host $_
# continue
#}

## copy-item $fullname \\.\nul\ -verbose -force out-file -file path $exepath\test1.txt -append
copy-item -LiteralPath $fullname \\.\nul\
$copyresult = $?

write-output "Copy of $fullname to nul returned $copyresult " >> "$exepath\$searchstring.txt"
}
Else{
$out5 = "The file "+$fullname+" has EV reparse information, and is offline, will not attempt to copy to nul device as copy selection not set to 'y'"
out-file -filepath "$exepath\$searchstring.txt" -inputobject $out5 -append

## copy functionality ## write-host "file " $fullname " has reparse information and is offline, will attempt to copy to nul device"
##
## copy $fullname \\.\nul\
}
}
}


## ------------------------------------------------
## Edited by Me (u know)
## ------------------------------------------------
}
## ------------------------------------------------

Write-Output "" >> $exepath\test1.txt
Write-Output "Processing Completed" >> $exepath\test1.txt
get-date out-file -filepath $exepath\test1.txt -append