Powershell remove prompt, but run 7 days back to yesterday - powershell

Currently I have a powershell that was written by someone else. It Connects to SQL and based on a date it will export the results against a Stored procedure...This Works fine Right now.
$FromDate = Read-Host "Enter Date of to Start (YYYY-MM-DD)"
$QueryText = "exec UDO_VW_ExportView_HISTORY #FromDate"
$SqlConnection = new-object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = $connString
$SqlCommand = $SqlConnection.CreateCommand()
$SqlCommand.CommandText = "EXEC UDO_VW_ExportView_HISTORY #FromDate"
# Add parameters to pass values to the stored procedure
$SqlCommand.Parameters.AddWithValue("#FromDate", $FromDate) | Out-Null
$DataAdapter = new-object System.Data.SqlClient.SqlDataAdapter $SqlCommand
$dataset = new-object System.Data.Dataset
Write-Host $DataAdapter.Fill($dataset) ' records have been exported.'
$dataset.Tables[0] | Export-CSV D:\_#Scripts\Daily_Export_HISTORY\Daily_Report_Txt\MyReport.csv -NoTypeInformation -Force
Write-Host 'New report D:\_#Scripts\Daily_Export_HISTORY\Daily_Report_Txt\MyReport.csv has been successfully generated'
(gc D:\_#Scripts\Daily_Export_HISTORY\Daily_Report_Txt\MyReport.csv) | % {$_ -replace '"""', '"'} | out-file D:\_#Scripts\Daily_Export_HISTORY\Daily_Report_Txt\Daily_Report_For_$FromDate.csv -Fo -En ascii
Remove-Item D:\_#Scripts\Daily_Export_HISTORY\Daily_Report_Txt\MyReport.csv
As you can see (i hope) the first line is:
$FromDate = Read-Host "Enter Date of to Start (YYYY-MM-DD)"
I just want it to get all transactions 7,6,5,4,3,2 days, and Yesterday as one export.
I also see in the code there are declared variables that may also be modified. Can you please look at this coed and provide an updated code that will achieve what I'm trying to do. I'm new to Powershell
Thank you so much!

You can replace :
$FromDate = Read-Host "Enter Date of to Start (YYYY-MM-DD)"
by
$FromDate = ([datetime]::Now).AddDays(-7).Date.ToString("yyyy-MM-dd")
It takes today date and time, remove 7 days, remove time and format it.

Related

Slow Output in Outlook via Powershell

I'm using Powershell to access Outlook Mails by creating COM Object.
When I search for particular Mail . PowerShell Iterates through all the mails due to which my output result is really slow and taking very long time.
I have already tried using Descending paramater in Sort-Object or filtering out by date but still results are slow.
$outlook = New-Object -comobject outlook.application
$inbox = $outlook.GetNamespace("MAPI")
$find = $inbox.GetDefaultFolder(6)
$find.Items | Where-Object{$_.SentOn -gt '27-Oct-2019 12:00 PM'}| Select-
Object -Property Subject,SentOn
Can someone please help me to generate faster results or provide a way to filter my search for particular time period.
Never loop through all items in your code. After all, you wouldn't write a SELECT query in SQL without a WHERE clause, would you?
Use Items.Find/FindNext or Items.Restrict to let the store provider do the job.
From the comment from #bluuf I looked into the EWS (exchange web service) and came up with this solution and its about 50% faster than your script.. Maybe it helps for you
$startDate = Get-Date
$MailboxSMTP = "peter.parker#home.com"
$dllpath = "C:\Program Files (x86)\Microsoft SQL Server Management Studio 18\Common7\IDE\Mashup\Microsoft.Exchange.WebServices.dll"
[void][Reflection.Assembly]::LoadFile($dllpath)
$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$service.UseDefaultCredentials = $true
$service.AutodiscoverURL($mailboxSMTP)
$mbMailbox = new-object Microsoft.Exchange.WebServices.Data.Mailbox($mailboxSMTP)
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
write-host "Number or unread Messages : " $inbox.UnreadCount
$emails = $inbox.FindItems(10000) | Where-Object { $_.DateTimeSent -gt '27-Oct-2019 12:00 PM'}
$endDate = Get-Date
New-TimeSpan -Start $startDate -End $endDate
Found the script here https://www.msxfaq.de/code/testews.htm
EDIT:
You can filter the results with EWS in a similar way as in #Dmitry solution
write-host "Number or unread Messages : " $inbox.UnreadCount
$view = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1)
$x = $inbox.FindItems($(New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThanOrEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::DateTimeReceived, '2019-10-27')),$view)
Or you can use it to filter for different attributes
$filter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::IsRead, $false)
Or
$filter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThanOrEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,'2019-10-10')
$x = $inbox.FindItems($filter,$view)

Write PowerShell console text to a file

I have a PowerShell script that connects to a DB and loops over some data.
After the script finishes or throws an error, I need to append whatever the text displayed in the console to a log file.
I couldn't achieve that using Write-Output because I don't want to save specific values, I just need the whole console text to be appended to a file.
Thank you.
EDIT :
In fact, the final result that I'm looking for, is a log file with timestamps, here is my code :
$server = "USER\SQLEXPRESS"
$database = "database_test"
$tablequery = "SELECT name from sys.tables"
#Delcare Connection Variables
$connectionTemplate = "Data Source={0};Integrated Security=SSPI;Initial Catalog={1};"
$connectionString = [string]::Format($connectionTemplate, $server, $database)
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
$command = New-Object System.Data.SqlClient.SqlCommand
$command.CommandText = $tablequery
$command.Connection = $connection
#Load up the Tables in a dataset
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $command
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$connection.Close()
$DriveName = (get-location).Drive.Name
$extractDir = md -Force "$($DriveName):\csv\files"
# Loop through all tables and export a CSV of the Table Data
foreach ($Row in $DataSet.Tables[0].Rows)
{
$connection.open();
#Specify the output location of your dump file
$command.CommandText = "SELECT * FROM [$($Row[0])]"
$command.Connection = $connection
(Get-Culture).NumberFormat.NumberDecimalSeparator = '.'
(Get-Culture).DateTimeFormat.ShortDatePattern = 'yyyy-MM-dd'
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $command
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$connection.Close()
$extractFile = "$($extractDir)\$($Row[0]).csv"
$DataSet.Tables[0] | Export-Csv $extractFile -NoTypeInformation -Encoding UTF8
}
I need to print each filename exported to csv ($extractFile) with a timestamp in a log file, and then if an error occurs, I need to print that too with a timestamp, and so on till the script finishes.
You can do this with Start-Transcript, try/catch/finally, or writing your own code (to store the console output to a variable, and append a text file with the contents when required). Note the -Append parameter with Start-Transcript.
Without code, it's difficult to know which of these to recommend.
Expanded
Now that you've added some code, see some additional info on each method. I'm not familiar with SQL via PowerShell so not sure what kind of output/errors you will be getting (regarding errors, specifically if there are terminating or non-terminating)
Transcript
Start-Transcript should go at the beginning, and Stop-Transcript at the end. This will log whatever is normally displayed on the console. Running Start-Transcript while a transcript is already being recorded will lead to a nasty error.
Start-Transcript -Path "c\temp\mylogfile.txt"
$server = "USER\SQLEXPRESS"
$database = "database_test"
$tablequery = "SELECT name from sys.tables"
...
...
$extractFile = "$($extractDir)\$($Row[0]).csv"
$DataSet.Tables[0] | Export-Csv $extractFile -NoTypeInformation -Encoding UTF8
}
Stop-Transcript
Terminating Errors
Add try/catch/finally as appropriate. You can be lazy and add this over the whole code, or do it properly and wrap the parts that could lead to terminating errors.
...
foreach ($Row in $DataSet.Tables[0].Rows)
{
try{
$connection.open();
#Specify the output location of your dump file
...
...
...
$extractFile = "$($extractDir)\$($Row[0]).csv"
$DataSet.Tables[0] | Export-Csv $extractFile -NoTypeInformation -Encoding UTF8
}catch{
# what to do if there is a terminating error
}finally{
# what to do whether there is an error or not
if(Test-Path "$($extractDir)\$($Row[0]).csv"){
# simple check: if a file was created, no error... right?
"$(Get-Date -f 'yyyy-MM-dd hh:mm:ss') $($Error[0])" | Out-File "c:\temp\mylogfile.txt" -Append
}else{
"$(Get-Date -f 'yyyy-MM-dd hh:mm:ss') $extractFile" | Out-File "c:\temp\mylogfile.txt" -Append
}
}
}
...
No Terminating Errors
Just add a line to export errors. Ensure you clear the automatic variable $Error each loop
...
foreach ($Row in $DataSet.Tables[0].Rows)
{
$Error.Clear()
$connection.open();
#Specify the output location of your dump file
...
...
...
$extractFile = "$($extractDir)\$($Row[0]).csv"
$DataSet.Tables[0] | Export-Csv $extractFile -NoTypeInformation -Encoding UTF8
# if there are no errors, write filename. Otherwise write errors
if([string]::IsNullOrEmpty($Error){
"$(Get-Date -f 'yyyy-MM-dd hh:mm:ss') $extractFile" | Out-File "c:\temp\mylogfile.txt" -Append
}else{
"$(Get-Date -f 'yyyy-MM-dd hh:mm:ss') $Error" | Out-File "c:\temp\mylogfile.txt" -Append
}
}
...
You could use Start-Transcript for debugging purposes:
Start-Transcript -path "C:\temp\myTranscript.txt"
Add at the start of your script and get all the console output written into C:\temp\myTranscript.txt

PostgreSQL Query export to CSV with PowerShell

$sf = "\\\\domain\\dept\\dcgsi\\Extracts\\Tableau_Unlicensed_Users.csv"
if (Test-Path $sf){
Remove-Item $sf
}
$query = #"
\\copy (SELECT Name
FROM _users
WHERE licensing_role_name = 'Unlicensed')
TO $sf
WITH CSV DELIMITER ','
"#
$conn = New-Object -ComObject ADODB.Connection
# use existing 64 bit ODBC System DSN that we set up manually
$conn.Open('PostgreSQL30')
$conn.Execute($query)
$conn.Close()
I keep getting an error about "\" on the line with the $conn.Execute() when I try and do this. I assume it has to do with character escaping and maybe I am doing it wrong.
Is there a better way to do this with PowerShell if I just need to get the name field of any record from _users and output it to CSV?
Eventually I will be adding more to this to loop through each record in the CSV and execute a tabcmd to remove all the users that are unlicensed.
$sf = "\\domain\dept\dcgsi\Extracts\Tableau_Unlicensed_Users.csv"
if (Test-Path $sf){
Remove-Item $sf
}
$query = #"
SELECT Name
FROM _users
WHERE licensing_role_name = 'Unlicensed'
"#
function Get-ODBC-Data{
$conn = New-Object System.Data.Odbc.OdbcConnection
$conn.ConnectionString = "DSN=PostgreSQL30;"
$conn.Open()
$cmd = New-object System.Data.Odbc.OdbcCommand($query, $conn)
$ds = New-Object system.Data.DataSet
(New-Object System.Data.Odbc.OdbcDataAdapter($cmd)).Fill($ds) | Out-Null
$conn.Close()
$ds.Tables[0] | Export-Csv $sf
}
Get-ODBC-Data
This did like 99% of what I need; I just have to process the csv now and drop the first two lines. The first line is a type info message and the second is the column header.

Format date inside table from database

I'm trying to create a script for querying a database, extract data and put it to an .csv file. This is the part of interest of the code:
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
$command = $connection.CreateCommand()
$command.CommandText = $query
$result = $command.ExecuteReader()
###########################
##PRSENTAZIONE DEI RISULTATI##
$table = New-Object System.Data.DataSet
$table.Load($result)
$table | Export-Csv -Path $fileName -Delimiter "|" -NoTypeInformation
I have 2 problems:
On Windows 2003 PowerShell -Delimiter parameter is not present
If I delete that parameter the ouput file presents a wrong format date.
username, ipaddress, yyyy-mm-dd hh:mm:ss (running the same query in Management Studio), username, ipaddress, "dd/mm/yyyy hh.mm.ss" (apexes included ; printing the $table).
How can I solve this?

How to add formatting to header column of csv file using powershell

I am able to run a stored procedure and export it to csv using the following code:
function TestSQLStoredPrc()
{
$connString = "Data Source=xxxxxx,1433;Initial Catalog=TestDB;User Id=TestUser; Password=YYYYYYY;"
$Reference = Read-Host "Enter Name";
$QueryText = "exec dbo.GetUsersCountByName 'Test'";
$SqlConnection = new-object System.Data.SqlClient.SqlConnection;
$SqlConnection.ConnectionString = $connString;
$SqlCommand = $SqlConnection.CreateCommand();
$SqlCommand.CommandText = "EXEC dbo.GetUsersCountByName 'Test'";
$DataAdapter = new-object System.Data.SqlClient.SqlDataAdapter $SqlCommand
$dataset = new-object System.Data.Dataset
Write-Host $DataAdapter.Fill($dataset) ' records have been exported.'
$dataset.Tables[0] | Export-CSV C:\MyReport.csv -Force -NoTypeInformation
Write-Host 'New report C:\MyReport.csv has been successfully generated'
}
TestSQLStoredPrc
I am able to get a csv file as output. But I need to apply background color and formatting to the header column of the output csv file.
Can anyone help me to resolve this issue by providing some sample example.
Thanks & Regards,
Santosh Kumar Patro
You can format it and save it as HTML, but you cannot do that and have it remain a .csv file. CSV is, by definition plaint text - there is no provision for storing foratting information in the file, only header names and values.