Automatically import ICS file to outlook.com - calendar

I have an *.ics file and want to import it to my calendar on outlook.com. How can I do this with a powershell script?
I need to either delete and recreate the calendar I import to, or clear the calendar before import.
Thanks in advance.

Try
Step 1: Read the contents of the ics file
Step 2: Parse it
Step 3: Use Outlook Application Object in Powershell
Step 4: Get the Calendar folder
Step 5: use the properties of the calendar folder to add the parsed content in step 2
#Folder containing ICS files
$ICSpath="C:\Users\test\testasdasd"
$ICSlist = get-childitem $ICSPath
Foreach ($i in $ICSlist )
{
$file= $i. fullname
$data = #{}
$content = Get-Content $file -Encoding UTF8
$content |
foreach-Object {
if($_.Contains(':')){
$z=#{ $_.split( ':')[0] =( $_.split( ':')[1]).Trim()}
$data. Add( $z. Keys, $z. Values)
}
}
$outlook = new-object -com Outlook.Application
$calendar = $outlook.Session.GetDefaultFolder(9)
$appt = $calendar.Items.Add(1)
$Body=[regex]::match($content,'(?<=\DESCRIPTION:).+(?=\DTEND:)', "singleline").value .trim ()
$Body= $Body -replace "\r\n\s"
$Body = $Body.replace("\,",",").replace("\n"," ")
$Body= $Body -replace "\s\s"
$Start = ($data.getEnumerator() | ?{ $_.Name -eq "DTSTART"}).Value -replace "T"
$Start = [datetime]::ParseExact ($Start ,"yyyyMMddHHmmss" ,$null )
$End = ($data.getEnumerator() | ?{ $_.Name -eq "DTEND"}).Value -replace "T"
$End = [datetime]::ParseExact ($End ,"yyyyMMddHHmmss" ,$null )
$Subject = ($data.getEnumerator() | ?{ $_.Name -eq "SUMMARY"}).Value
$Location = ($data.getEnumerator() | ?{ $_.Name -eq "LOCATION"}).Value
$appt.Start = $Start
$appt.End = $End
$appt.Subject = $Subject
$appt.Categories = "Presentations" #Pick your own category!
$appt.BusyStatus = 0 # 0=Free
$appt.Location = $Location
$appt.Body = $Body
$appt.ReminderMinutesBeforeStart = 15 #Customize if you want
$appt.Save()
if ($appt.Saved)
{ write-host "Appointment saved."}
Else {write-host "Appointment NOT saved."}
}
Acknowledging "thescriptkeeper.wordpress.com" for the script

Related

Powershell script for reporting old folders on multiple shares

I am hoping for some guidance. I need to analyze multiple shares for folders that have not been modified in 6 months. For each share, I defined specific paths that need to be examined. A csv should be generated for each share. The powershell script works fine for checking a single share but I can't get it work correctly for multiple shares. Here's a sample of the script.
$age = (Get-Date).AddMonths(-6)
# Export path
$outputPath = "D:\Scripting\xPowershell_Results\"
# Export file name
$FilePath1 = "OldMediaPath1.csv"
$FilePath2 = "OldMediaPath2.csv"
# Paths to scan
$CheckPath1 = #(
"\\servername\share1\Projects"
"\\servername\share1\Restored"
)
$CheckPath2 = #(
"\\servername\share2\Graphics"
)
$folders = dir $CheckPath1 | where {$_.PSiscontainer -eq $true} | Where-Object {($_.LastWriteTime -lt $age)}
$results = foreach ($folder in $folders) {
$bytecount = (dir $folder.fullname -recurse | Measure-Object -property length -sum).sum
switch ($bytecount)
{
{$_ -lt 1KB} { $size = "{0:N0} Bytes" -f $_; break }
{$_ -lt 1MB} { $size = "{0:N2} KB" -f ($_ / 1KB); break }
{$_ -lt 1GB} { $size = "{0:N2} MB" -f ($_ / 1MB); break }
{$_ -lt 1TB} { $size = "{0:N2} GB" -f ($_ / 1GB); break }
{$_ -lt 1PB} { $size = "{0:N2} TB" -f ($_ / 1TB); break }
default { $size = "{0:N2} PB" -f ($_ / 1PB) }
}
[PSCustomObject]#{
Name = $folder.fullname
Size = $size
LastWriteTime = $folder.LastWriteTime
}
}
$results | Export-Csv $outputPath$FilePath1 -NoTypeInformation

Powershell Invoke-Sqlcmd : Conversion failed when converting date and/or time from character string

I am trying to import a datetime from PowerShell into a SQL Table. It's the only thing stored in that table.
When I run this code: (The value stored in the variable is: 11/19/2020 09:51:40.3244656)
$location = 'path'
Set-Location $location
$c = Get-ChildItem 'path' | Sort { $_.LastWriteTime } | select -last 1 | foreach { $a = $_; $b = Get-Acl $_.FullName; Add-Member -InputObject $b -Name "LastWriteTime" -MemberType NoteProperty -Value $a.LastWriteTime; $b }
$c.LastWriteTime
$date = $c.LastWriteTime
Function Get-Datetime([datetime]$Date = $date ) {
$DT = Get-Date -Date $Date
[string]$DateTime2 = $DT.Month.ToString() + '/'
[string]$DateTime2 += $DT.Day.ToString() + '/'
[string]$DateTime2 += $DT.Year.ToString() + ' '
[string]$DateTime2 += $DT.TimeOfDay.ToString()
return $DateTime2
}
$finaldate = Get-Datetime
#$dateFormatted = $date -format
Invoke-Sqlcmd -ServerInstance "Server" -Database "db" -query "Update [server].[schema].[table] Set [columnName] = '$finaldate'"
I get this error:
Powershell Invoke-Sqlcmd : Conversion failed when converting date and/or time from character string.
How can I get the Powershell command to update the table?
Thank you for your help.
#NekoMusume helped me get to the answer to this specific question. After adding this line, (modified from #NekoMusume's comment): Thanks #NekoMusume! (If you want to answer, I'll mark it for you.)
$finaldate = Get-Date $finaldate -Format "yyyy/MM/dd HH:mm"
The code worked. Final Working code
$location = 'path'
Set-Location $location
$c = Get-ChildItem 'path' | Sort { $_.LastWriteTime } | select -last 1 | foreach { $a = $_; $b = Get-Acl $_.FullName; Add-Member -InputObject $b -Name "LastWriteTime" -MemberType NoteProperty -Value $a.LastWriteTime; $b }
$c.LastWriteTime
$date = $c.LastWriteTime
Function Get-Datetime([datetime]$Date = $date ) {
$DT = Get-Date -Date $Date
[string]$DateTime2 = $DT.Month.ToString() + '/'
[string]$DateTime2 += $DT.Day.ToString() + '/'
[string]$DateTime2 += $DT.Year.ToString() + ' '
[string]$DateTime2 += $DT.TimeOfDay.ToString()
return $DateTime2
}
$finaldate = Get-Datetime
$finaldate = Get-Date $finaldate -Format "yyyy/MM/dd HH:mm"
#$dateFormatted = $date -format
Invoke-Sqlcmd -ServerInstance "Server" -Database "db" -query "Update [server].[schema].[table] Set [columnName] = '$finaldate'"

File sorting based on file content (string)

I want to build a modular script that sorts files based on content (strings/Get-Content in PowerShell).
Requirement:
Defining a directory. ($directory)
start a foreach loop: foreach
list items in the directory & full path in memory
$FilePath in Get-ChildItem $directory | Select-Object -ExpandPropert FullName
Load content of one file at a time in the memory
$content = Get-Content $FilePath
Search for the keyword and copy the file once a particular keyword is found.
if ($content -match 'keyword1') { Copy-Item $FilePath $OutputPath }
While I am able to do this in a static manner using the below mentioned code, I wanted to modularise it for reuse.
[string] $Directory = "parth to source directory";
[string] $outpath1 = "outpath for keyword1";
[string] $OutputPath2 = "outpath for keyword2";
[string] $OutputPath3 = "outpath for keyword3";
foreach ($FilePath = Get-ChildItem $Directory | Select-Object -ExpandProperty FullName) {
[string] $content = Get-Content $FilePath
if ($content -match 'keyword1') {
Copy-Item $FilePath $OutputPath
} elseif ($content -match 'keyword2') {
Copy-Item $FilePath $OutputPath2
} else {
Copy-Item $FilePath $keyword3
}
}
My questions:
Is it possible to define keywords in a single array? If so how do that in PowerShell? (keyword1, keyword2, keyword3)
Run keywords sequentially in the files and whenever one keyword is detected, the file is copied to it's designated folder. Can I have this done in modular fashion or will I have to define directory for each keyword?
The reason I am doing this is because while the script is being used for 2 or 3 keywords as of now, it will be used for over 50 keywords and allowing reuse should help.
What you describe could be achieved with a hashtable and a nested loop:
$outpath = #{
'keyword1' = 'outpath for keyword1'
'keyword2' = 'outpath for keyword2'
'keyword3' = 'outpath for keyword3'
}
foreach ($FilePath in Get-ChildItem $Directory | Select-Object -Expand FullName) {
$content = Get-Content $FilePath
foreach ($keyword in $outpath.Keys) {
if ($content -match $keyword) {
Copy-Item $FilePath $outpath[$keyword]
break
}
}
}
Alternatively you could use a switch statement:
$outpath = #{
'keyword1' = 'outpath for keyword1'
'keyword2' = 'outpath for keyword2'
'keyword3' = 'outpath for keyword3'
}
$pattern = ($outpath.Keys | ForEach-Object { [regex]::Escape($_) }) -join '|'
foreach ($FilePath in Get-ChildItem $Directory | Select-Object -Expand FullName) {
$content = Get-Content $FilePath
switch -regex ($content) {
$pattern {
Copy-Item $FilePath $outpath[$keyword]
break
}
}
}
The latter would also give you a simple way of specifying a fallback destination path if you also want to handle files with no matching keyword.
$fallbackpath = '...'
foreach ($FilePath in Get-ChildItem $Directory | Select-Object -Expand FullName) {
$content = Get-Content $FilePath
switch -regex ($content) {
$pattern {
Copy-Item $FilePath $outpath[$keyword]
break
}
default {
Copy-Item $FilePath $fallbackpath
break
}
}
}

How can I get a output from a powershell function into a output file for example txt?

I have made a create function in windows powershell:
function create(){
param(
$searchBase = "OU=Customers,DC=test,DC=nl",
$NewOUs = #(Import-csv -Path $txt_csv.Text -Delimiter ";"),
[switch]$ProtectOU
)
$Protect = $true
If ($ProtectOU){$Protect = $true}
<# ------- CREATE OU ------- #>
foreach ($NewOU in $NewOUs) {
try {
New-ADOrganizationalUnit -Name $NewOU.company -Description $NewOU.description -Path $searchBase -ProtectedFromAccidentalDeletion $Protect
}
catch {
Write-Host "OU already exists"
}
}
$UserList = Import-Csv -Path $txt_csv.Text -Delimiter ";"
<# ------- CREATE USERS ------- #>
foreach ($User in $UserList) {
$OU = $User.path
$UPN = $User.UPN
$Password = $User.password
$Detailedname = $User.firstname + " " + $User.Lastname
$UserFirstname = $User.Firstname
$FirstLetterFirstname = $UserFirstname.substring(0,1)
$SAM = $User.UPN
$Company = $User.company
$Description = $User.description
$AccountExpirationDate = $User.accountexpirationdate
$params = #{ 'Name'=$Detailedname;
'SamAccountName'=$SAM;
'UserPrincipalName'=$UPN+'#test.nl';
'DisplayName'=$Detailedname;
'GivenName'=$UserFirstname;
'Surname'=$User.Lastname;
'AccountPassword'=(ConvertTo-SecureString $Password -AsPlainText -Force);
'Enabled'=$True;
'PasswordNeverExpires'=$True;
'Path'=$OU;
'Company'=$Company;
'Description'=$Description;
'AccountExpirationDate'=$AccountExpirationDate
'HomeDrive' = "H:"
'HomeDirectory' = "\\home\userdata$\$SAM"
'ProfilePath'="\\dc-test\User Profiles$\$SAM"
}
New-ADUser #params
}
I want this create function as a output file for example in a txt.
This is my wpf button object:
$button_add.Add_Click({create})
When I click on the button the output must generated a output file. I already tried a lot of solutions such ass:
Create | out-file but I don't get the information I want:
source: https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.utility/out-file
Is it possible to do this?
Kind regards
You would want to do the following:
"processing New-ADUser with $params" | Out-File log.txt -Append
try {
New-ADUser #params
"Created $UPN" | Out-File log.txt -Append
}
catch {
$_ | Out-File log.txt -Append
}
or you could just pass the output of New-ADUser to the Out-File:
New-ADUser #params -PassThru | Out-File log.txt -Append

Find file extension in folder and sum total size

I am trying to find all file extension in a folder and subfolders and generate a list. I found a oneliner but it do not generate the list as i want. i got mutiple of paths so i do this.
$date = get-date -Format d
$File = "C:\NoBackup\FolderPaths.txt"
foreach ($Folder in (Get-Content $File)) {
Get-ChildItem $Share -Recurse -ErrorAction SilentlyContinue | Group-Object extension | Select-Object #{Name="Folder";Expression={$Folder}}, name, #{n='TotalSize';e={$_.group | ForEach-Object -Begin {$size=0} -Process {$size += ([decimal]::round($_.Length / 1MB))} -End {"$size MB"}}} | Sort-Object -Property 'TotalSize' -Descending | Format-Table -AutoSize
}
This will give a new header foreach folder in folderpaths, and i need the result be like this
.ext1 .ext2 .ext3 .ext4
D:\Folder1 5MB 12MB 20MB 8MB
D:\Folder2 10MB 54MB 12MB 3MB
D:\Folder3 2MB 12MB 20MB 100MB
I cant find out to rewrite the code to get what i need. Hope you can help me out with this.
The script works now. I needed to change
foreach($folder in $folders)
To
foreach($folder in (Get-Content $file))
It is not short or sweet, but try this:
function ConvertTo-Units($decimal)
{
$value = [decimal]::Round($decimal/1mb,2)
$units = "MB"
if($value -eq 0)
{
$value = [decimal]::Round($decimal/1kb,2)
$units = "KB"
}
return "{0} {1}" -f $value,$units
}
$File = "C:\NoBackup\FolderPaths.txt"
$fileData = #{}
foreach ($folder in (Get-Content $file))
{
$files = Get-ChildItem $folder -Recurse -ErrorAction SilentlyContinue -File
$fileData[$folder] = $files | Select-Object extension,length | %{$h = #{}} { $h[$_.extension] += $_.length } { $h}
}
$extensions = $fileData.Keys | % { $fileData[$_].Keys } | % tolower | Select-Object -Unique | ? { $_ }
$properties = #(
#{Name="Folder";Expression={$_}}
)
$extensions | % {$properties += #{Name="$_";Expression=[scriptblock]::Create("ConvertTo-Units `$fileData[`$folder][""$_""]")}}
$result = #()
foreach($folder in $folders)
{
$result += $folder | Select-Object $properties
}
$result | ft * -AutoSize -force

Resources