I'm newbie to powershell, and I have a challenge on process my script. It did everything perfectly, but it wont move the message to the target folder and I don't know why.
I thought maybe to process at end cycle, but the issue is that I can encour that will transfer also file that have not any reference, and I would avoid to process something that I have no info about.
I tried this
$MailboxName = "fatture#abc.com"
write-host "Now Processing" -ForegroundColor Yellow
write-host "Searching on Fatture" -ForegroundColor Yellow
$olFolderInbox = 6
$outlook = new-object -com outlook.application;
$namespace = $outlook.GetNameSpace("MAPI");
$recipient = $namespace.CreateRecipient($MailboxName)
$inbox = $namespace.GetSharedDefaultFolder($recipient,6)
$messages = $inbox.Folders.Item("Carriers").folders.Item("Gpac").folders.item("BLR")
$MoveTarget = $inbox.Folders.Item("Carriers").folders.Item("Gpac").folders.item("BLS")
$filepath = "C:\temp\FATTURE\Automation\"
$messages.Items | % {
Write-Host "New Message " $_.Subject
$msg = $_
$Ref = $_.Subject -replace ' ',''
$RefStr = $ref.split('#')
$SearchSTR = $RefStr[2]
write-host $SearchStr
# $invNbr = $body.Substring($body.IndexOf("INVOICE NO")+19,10)
#write-host "The Invoice Number is : $invNbr" -ForegroundColor Cyan
write-host "Querying for $SearchSTR" -ForegroundColor Green
$t = (Query_file($SearchSTR))[-1].CONSOL_REF
write-host "File Found : $t" -ForegroundColor Cyan
write-host $t
if ($t -ne $null) {
$filetype = $t.Substring(0,1)
$date = Get-Date -format "yyyyMMddhhmmss"
write-host "Today is Date is $date" -ForegroundColor Red
Switch($filetype.tostring())
{
{($_ -eq 1) -or ($_ -eq 2) -or ($_ -eq 7) -or ($_ -eq 7) -or ($_ -eq 8) }{($dept = "0001"), ($dept1 = "ZLAG")}
{($_ -eq "F") -or ($_ -eq "V") -or ($_ -eq "M")}{($dept = "0002"), ($dept1 = "Zero"), ($type = "MOR")}
{($_ -eq 3) -or ($_ -eq 5) -or ($_ -eq "J")} {($dept = "0028"), ($dept1 = "One"), ($type = "OBR") }
{($_ -eq 9)} {($dept = "0031"), ($dept1 = "CONSOLE")}
}
write-host "The KEY TYPE is $dept1 " -ForegroundColor Yellow
$fileStr = $t + "_INV_" + $dept + "_$date_.tsk"
write-host " FILE Path: " $fileStr -ForegroundColor Cyan
$msg.attachments | ?{$_.filename -like "*.pdf"} | %{
$file = $filestr
$_.saveasfile((Join-Path $filepath $filestr))
}
$msg.UnRead = $false
$msg.Move($MoveTarget)
}
#fine cycle messages
}
I tried to move from the cycle but the issue is that it goes for all of email, instead, I want to process only the email that should be. I would like when the attachment has being downloaded, that the email will be moved.
Related
I am trying to convert DOC files with macros to DOTM with macros. My code changes the files but after the marco section is totally broken. When I convert it manually my macro code stays.
My code is:
function ReleaseRef ($ref) {
if($ref){
([System.Runtime.InteropServices.Marshal]::ReleaseComObject(
[System.__ComObject]$ref) -gt 0)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
}
function Convert-DOC{
Param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$filepath,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$filefilter
)
try {
$files = Get-ChildItem $filepath -Include "$filefilter" -recurse -ErrorAction SilentlyContinue | Where-Object { ($_.PSIsContainer -eq $false) -and ( $_.Extension -like "$filefilter") }
$totalfiles = $files.Count
[int]$currentfile = 0
Write-Host "converting files... [$totalfiles]"
#word object********************************
#load dotnet assembly
Add-Type -AssemblyName Microsoft.Office.Interop.Word
#create word object
$word = New-Object -ComObject Word.Application -Verbose:$false
$word.visible = $true
$word.DisplayAlerts = [Microsoft.Office.InterOp.Word.WdAlertLevel]::wdAlertsNone
foreach ($file in $files) {
#Current file number
[int]$currentfile = [int]$currentfile + 1
#Check for password
$catch = $false
try {
#open file
Write-Host $file
$worddoc = $word.Documents.Open($file.FullName, $null, $null, $null, "")
} catch {
#if error, file has password
Write-Host "$file is protected by Password, skipping..." -ForegroundColor Yellow
$catch = $true
continue
}
if ($catch -eq $false) {
try {
#**********convert file**********
write-host "converting " $file.fullname "file $currentfile of $totalfiles" -ForegroundColor DarkGreen
#check for links
if([IO.Path]::GetExtension($file) -eq ".doc"){
#check for macros in in file
if ($worddoc.HasVBProject) {
$doFixedFormat = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatXMLDocumentMacroEnabled
$newfile = ($file.fullname).substring(0, ($file.FullName).lastindexOf("."))
$newfile += ".docm"
} else {
$doFixedFormat = [Microsoft.Office.Interop.Word.XlFileFormat]::wdFormatXMLDocument
$newfile = ($file.fullname).substring(0, ($file.FullName).lastindexOf("."))
$newfile += ".docx"
}
}
#save file
if(Test-Path $newfile){
Write-host "$newfile already exists" -ForegroundColor Yellow
} else {
$worddoc.SaveAs($newfile, $doFixedFormat )
}
#close file
$worddoc.close()
Write-Host "done" -ForegroundColor DarkGreen
#**********Garbage Collector**********
$gc_int++
if([int]$gc_int -gt 5){
Write-Host 'Run Garbage Collector' -ForegroundColor DarkBlue -BackgroundColor White
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
[int]$gc_int = 0
}
} catch {
$formatstring = "{0} : {1}`n{2}`n" +
" + CategoryInfo : {3}`n" +
" + FullyQualifiedErrorId : {4}`n" +
" + Filename : {5}`n"
$fields = $_.InvocationInfo.MyCommand.Name,
$_.ErrorDetails.Message,
$_.InvocationInfo.PositionMessage,
$_.CategoryInfo.ToString(),
$_.FullyQualifiedErrorId,
$file.fullname
Write-Host -Foreground Red -Background Black ($formatstring -f $fields)
"$fields" | Out-File ($scriptpath + '\error_convert.log') -Append
}
}
}
} finally {
#**********clean-up************
Write-Host ""
Write-Host "Cleaning Up" -ForegroundColor DarkMagenta
Write-Host "Quiting Word"
$word.Quit()
Write-Host "Garbage Collector"
[gc]::collect()
[gc]::WaitForPendingFinalizers()
Write-Host "Release Com Object Workbook"
$a = ReleaseRef($worddoc)
Write-Host "Release Com Object Word"
$a = ReleaseRef($word)
Write-Host "Finishing Clean-Up"
}
}
Convert-DOC -filepath "C:\_testmacro\" -filefilter "*.doc"
What I do is, checking if the file has a VB part and is so setting the extension:
[Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatXMLDocumentMacroEnabled
and then save it:
$worddoc.SaveAs($newfile, $doFixedFormat)
A similar function with XLS and XLAM works fine
Edit:
seems like I was missing a $worddoc.Convert() but now struggling with checkin/checkout
As my edit stated, I missed the convert command:
$worddoc.Convert()
$worddoc.SaveAs($newfile, $doFixedFormat)
before saving
# Source / credit:
# https://social.technet.microsoft.com/wiki/contents/articles/18996.active-directory-powershell-script-to-list-all-spns-used.aspx
cls
$search = New-Object DirectoryServices.DirectorySearcher([ADSI]"")
$search.filter = "(servicePrincipalName=*)"
## You can use this to filter for OU's:
## $results = $search.Findall() | ?{ $_.path -like '*OU=whatever,DC=whatever,DC=whatever*' }
$results = $search.Findall()
foreach( $result in $results ) {
$userEntry = $result.GetDirectoryEntry()
Write-host "Object Name = " $userEntry.name -backgroundcolor "yellow" -foregroundcolor "black"
Write-host "DN = " $userEntry.distinguishedName
Write-host "Object Cat. = " $userEntry.objectCategory
Write-host "servicePrincipalNames"
$i=1
foreach( $SPN in $userEntry.servicePrincipalName ) {
Write-host "SPN(" $i ") = " $SPN
$i+=1
}
Write-host ""
}
nslookup $SPN
I would like to use nslookup on the service principal names.
I am trying to use nested IF statements to check a AD-Computer Attribute and if it is not either VM or VeraCrypt, use Manage-BDE to check the Bitlocker status.
When I use just Get-Adcomputer <name> -Properties extensionAttribute1 | select extensionAttribute1 it returns the expected result VM.
When I do
$Attribute = Get-Adcomputer <name> -Properties extensionAttribute1 | select extensionAttribute1
Write-Host $Attribute
I get #{extensionAttribute1=VM}
I have tried many using -Notlike "*VM* but this did not work.
Here is my code.
# -----------------------
# Define global variables
# -----------------------
$ScanCount = 0
$UnprotectedCount = 0
$Date = Get-Date -Format yyyyMMdd
$StartDate = Get-Date -Format HH:mm:ss
$ReportFile = "C:\BitLocker_Status\BitLocker_Status.csv"
$BackupFile = "C:\BitLocker_Status\BitLocker_Status_Backup$BackupCopy'_$Date.csv"
$OutputArray = #()
$BackupCopy = 0
$SearchBase = "DC=Merallis,DC=net"
# ----------------------------------------
# Checking backing up output file
# ----------------------------------------
if (Test-Path $ReportFile) {
Rename-Item -Path $ReportFile -newname $BackupFile
$BackupCopy = $BackupCopy + 1
}
Else {
$BackupCopy = 0
}
# ----------------------------------------
# Build array from list of computers in AD
# ----------------------------------------
Write-Host -NoNewline "- Gathering a list of Computers from Active Directory..."
Try
{
$Computers = Get-ADComputer -SearchBase $SearchBase -Filter * -Properties Name,Description | Sort-Object
Write-Host -ForegroundColor Green "Success"
}
Catch
{
Write-Host -ForegroundColor Red "Failed ($_)"
}
# -------------------------------------------------
# Use the Manage-BDE command to query each computer
# -------------------------------------------------
Write-Host "- Querying BitLocker status..."
ForEach ($Computer in $Computers)
{
$Name = $Computer.Name
$Description = $Computer.Description
$BDE = Manage-BDE -ComputerName $Computer.Name -Status C:
# -------------------------------------------------
# Use the Get-ADComputer command to query the current attribute for each computer
# -------------------------------------------------
$Attribute = Get-ADComputer $Name -Properties extensionAttribute1 | select extensionAttribute1
Write-Host -nonewline " - $Name ..."
If ($Attribute -notlike "*VM*" -or $Attribute -notlike "*VeraCrypt*") {
If ($BDE -Like "*An error occurred while connecting*") {Write-Host -ForegroundColor Yellow "Unable to connect"; $Status = "Unable to connect"; Set-ADComputer -identity $Name -Replace #{"ExtensionAttribute1"=$Status}}
ElseIf ($BDE -Like "*Protection On*") {Write-Host -ForegroundColor Green "Protected"; $Status = "Protected"; Set-ADComputer -identity $Name -Replace #{"ExtensionAttribute1"=$Status}}
ElseIf ($BDE -Like "*Protection Off*") {Write-Host -ForegroundColor Red $Status; $Status = "Not protected"; $UnprotectedCount = $UnprotectedCount + 1 ; Set-ADComputer -identity $Name -Replace #{"ExtensionAttribute1"=$Status}}
ElseIf ($BDE -Like "*The term 'manage-bde'*") {Write-Host -ForegroundColor Red "error manage-bd!"; $Status = "Not protected"; $UnprotectedCount = $UnprotectedCount + 1}
Else {Set-ADComputer -identity $Name -Replace #{"ExtensionAttribute1"="Unknown"}}
}
$ScanCount = $ScanCount +1
$OutputArray += New-Object PsObject -Property #{
'Computer name' = $Computer.Name
'Description' = $Computer.Description
'BitLocker status' = $Status
}
}
# -----------------
# Generate a report
# -----------------
Write-Host -NoNewline "- Saving report..."
Try
{
$OutputArray | Export-CSV -NoTypeInformation $ReportFile
Write-Host -ForegroundColor Green "Success"
}
Catch
{
Write-Host -ForegroundColor Red "Failed ($_)"
}
# -----------------------------------------
# Display completion message and statistics
# -----------------------------------------
$EndDate = Get-Date -Format HH:mm:ss
$Duration = New-TimeSpan $StartDate $EndDate
Write-Host ""
Write-Host "-------------------------------------------------------------"
Write-Host "Script complete. Start time: $StartDate, End time: $EndDate"
Write-Host "Scanned $ScanCount computers. $UnprotectedCount are unprotected!"
Write-Host "-------------------------------------------------------------"man
Write-Host ""
If you want to filter objects from list based on some property value then you can use Where-Object
i.e. Website list ( without "default" website Name )
$YOURLIST = Get-Website
$YOURLIST | Where-Object { $_.Name -notlike "*Default*" }
The title says it all. I have been returning output from every iteration of both of the below foreach loops (see the Write-Host and Write-Output lines), but the application that is using this script (Nagios) can't handle that much data. Therefore, I would like to only return 1 output at a time. Basically "All apps okay" or "app(s) down: then list the apps not returning 200 response code".
I have no idea how to do this as getting the foreach loops to work in the first place was quite the challenge for me.
$ok = 0
$warning = 1
$critical = 2
$unknown = 3
$appPool = get-webapplication
$errorcode = 0
$time_errorcode = 0
foreach($a in $appPool) {
$app = $a.Attributes[0].Value;
$url = "http://localhost$app/apitest/index"
$HTTP_Request = [System.Net.WebRequest]::Create($url)
$HTTP_Response = try{ $HTTP_Request.GetResponse() }catch {$exceptionMessage = $_.Exception.Message
$exceptionItem = $app}
[int]$HTTP_Response.StatusCode -ne 200
$statuscode = [int]$HTTP_Response.StatusCode
Write-Host "$app status code: $statuscode"
if ($HTTP_Response.StatusCode.value__ -ne 200) {
[int]$errorcode = 1
}
}
foreach($t in $appPool){
$app = $t.Attributes[0].Value;
$url = "http://localhost$app/apitest/index"
$output = "$PSScriptRoot\10meg.test"
$start_time = Get-Date
try {Invoke-WebRequest -Uri $url -OutFile $output} catch {
$exceptionMessage = $_.Exception.Message
$exceptionItem = $app
Write-Output "$app error: $exceptionMessage"}
Write-Output "$app Time taken: $((Get-Date).Subtract($start_time).milliSeconds) millisecond(s)"
$timetaken = $((Get-Date).Subtract($start_time).milliSeconds)
if ($timetaken.StatusCode.value__ -ge 500) {
[int]$time_errorcode = 1
}
}
#Uncomment for testing
#Write-Output $time_errorcode
#Write-Output $errorcode
if (($errorcode -eq 0 -and $time_errorcode -eq 0)){exit $ok}
if (($errorcode -eq 1 -and $time_errorcode -eq 0)){exit $critical}
if (($errorcode -eq 0 -and $time_errorcode -eq 1)){exit $warning}
if (($errorcode -eq 1 -and $time_errorcode -eq 1)){exit $critical}
else {exit $unknown}
Here's my approach. UNTESTED. Just to give you an idea to work with.
$appPool = Get-WebApplication
$errorcode = 0
$time_errorcode = 0
# Using a hashset ensures every app is contained only once
$appsDown = New-Object "System.Collections.Generic.HashSet[string]"
foreach($a in $appPool) {
$app = $a.Attributes[0].Value;
$url = "http://localhost$app/apitest/index"
### Test response code ###
$HTTP_Request = [System.Net.WebRequest]::Create($url)
$HTTP_Response = $null
try {
$HTTP_Response = $HTTP_Request.GetResponse()
} catch {
# for test
Write-Host $_
}
if ($null -eq $HTTP_Response -or [int]$HTTP_Response.StatusCode -ne 200 ) {
[int]$errorcode = 1
[void]$appsDown.Add($app)
}
### Test response time ###
$output = "$PSScriptRoot\10meg.test"
$start_time = Get-Date
$timetaken = -1
try {
Invoke-WebRequest -Uri $url -OutFile $output
$timetaken = ((Get-Date) - $start_time).TotalMilliSeconds
} catch {
# for test
Write-Host $_
}
if ($timetaken -lt 0 -or $timetaken -ge 500) {
[int]$time_errorcode = 1
[void]$appsDown.Add($app)
}
}
# Output the results here
if ($appsDown.Count -eq 0) {
Write-Output "All apps okay"
}
else {
Write-Output ($appsDown.Count.ToString() + "app(s) down")
$appsDown | sort | foreach {
Write-Output $_
}
}
if (($errorcode -eq 0 -and $time_errorcode -eq 0)){exit $ok}
if (($errorcode -eq 1 -and $time_errorcode -eq 0)){exit $critical}
if (($errorcode -eq 0 -and $time_errorcode -eq 1)){exit $warning}
if (($errorcode -eq 1 -and $time_errorcode -eq 1)){exit $critical}
else {exit $unknown}
Explanations:
$appsDown = New-Object "System.Collections.Generic.HashSet[string]"
Create a new instance of a .NET HashSet to hold the app names. (It's an unordered collection where every value is stored only once.)
[void]$appsDown.Add($app)
Add the app name to the collection. [void] is there to prevent the method's return value to be sent to the pipeline.
This may help you:
$list = #()
Foreach(x in y){
$item = #{}
If(x.error -eq 200){
$item.Name = x.Name
}
$obj = New-Object PSObject -Property $item
$list += $obj
}
Adding these parts will leave you with a list of appsnames in the variable $list
I'm using PowerShell to add or remove text from file. I'm keep getting funny text in my file.
This only happens when I have removed the line from the text file and when I try to add new line I get funny text.
cls
IMPORT-MODULE ActiveDirectory
$fileLocation = "E:\Script\MatchCadTest\ptc.opt";
function addUser( $username=''){
$user = Get-ADUser -Identity $username -ErrorAction SilentlyContinue;
$userFullName = $user.Name;
$empty = [string]::IsNullOrEmpty($userFullName);
if ( !($empty) ){
$userExisted = Get-Content $fileLocation | Select-String "$username" -quiet
if( ! $userExisted ){
$newLocation = "E:\Script\MatchCadTest\backup\";
if((Test-Path -Path $fileLocation)) {
Copy-Item "$fileLocation" "$newLocation"
}
$date = Get-Date -Format "d-M-y Hms";
$newName = "ptc_$date.opt"
Rename-Item "$newLocation\ptc.opt" $newName
# Add-Content $fileLocation ""
Add-Content -Path $fileLocation -Value "# $userFullName";
Add-Content -Path $fileLocation -Value "INCLUDE MATHCAD USER $username";
Write-Host "User has been added to file. Please restart the service." -BackgroundColor Green -ForegroundColor Black
}
else{
Write-Host "User already existed" -BackgroundColor Red -ForegroundColor White
}
}
}
function removeUser( $username=''){
$user = Get-ADUser -Identity $username -ErrorAction SilentlyContinue;
# $user
$userFullName = $user.Name;
$empty = [string]::IsNullOrEmpty($userFullName);
if ( !($empty) ){
$userExisted = Get-Content $fileLocation | Select-String "$username" -quiet
if( $userExisted ){
$remove="# $userFullName";
$removeUser = (Get-Content $fileLocation);
$removeUser | where {$_ -ne $remove};
$remove="INCLUDE MATHCAD USER $username";
$removeUser | where {$_ -ne $remove}
$removeUser |Out-File $fileLocation;
#$removeUser = (Get-Content $fileLocation) | where {$_ -ne $remove} | Out-File $fileLocation;
#$content = Get-Content $fileLocation
#$content | Foreach {$_.TrimEnd()} | Set-Content $fileLocation
Write-Host "User removed" -BackgroundColor Green -ForegroundColor Black
}
else{
Write-Host "User does not existed" -BackgroundColor Red -ForegroundColor White
}
}
else{
Write-Host "User not found in ad" -BackgroundColor Red -ForegroundColor White
}
}
$option=''
while ( $option -ne 0){
Write-Host "What would you like to do?"
Write-Host "1= Add new user"
Write-Host "2= Remove user"
Write-Host "0= No (Exit)"
$option = Read-Host "Select option"
$username = Read-Host "Please enter Username"
if( $option -eq 0 ){
exit 1
}
elseif( $option -eq 1){
addUser($username);
}
elseif ( $option -eq 22){
removeUser ($username);
}
else{
cls
Write-Host
Write-Host " Invaild Choice " -BackgroundColor Red #-ForegroundColor White
Write-Host
}
#Reset
$option=444;
$username="";
$userFullName="";
$user="";
$empty="";
}
When I remove the line of text from file and add a new user, it's all a funny text string:
See below
‣潍慨浭摡䴠橡摩义䱃䑕⁅䅍䡔䅃⁄单剅洠ㅭ㘳㐰ല
I have a text file with following information.
- // Full name 1
- User ID of User 1
- // Full name 2
- User ID of User 2
* // Full name 3
* User ID of User 3
* // Full name 4
* User ID of User 4
* // Full name 5
* User ID of User 5
* // Full name 6
* User ID of User 6
* // Full name 7
* User ID of User 7
* // Full name 8
* User ID of User 8
If you see that user 5 and 6 or 7 and 8 has extra space which i wont to remove and ad just sinlge space.
I think you need to set the encoding for your Add-Content
Try: Add-Content -Encoding UTF8 -Path $fileLocation -Value "# $userFullName";