I have a simple script that will create an Outlook Calendar Item (found online) and it will create a calendar item just fine, but it puts it on my default calendar. How can I get it to put it on a specific calendar? This is what I have.
$outlook = new-object -com outlook.application
$CalItem = "1"
$newAppt = $outlook.CreateItem($CalItem)
$newAppt.Body = "Test Body222"
$newAppt.Subject = "Test Subject222"
$newAppt.Start = $OutObject.StartDate
$newAppt.End = $OutObject.ImpEndDate
$newAppt.BusyStatus = 0
$newAppt.Save()
Instead of using Application.CreateItem (whcih always uses the appropriate default folder), open the target folder programmatically and use MAPIFolder.Items.Add.
I was able to make it happen with this
# Instantiate a new Outlook object
$ol = new-object -ComObject "Outlook.Application"
# Map to the MAPI namespace
$MyNameSpace = $ol.getnamespace("mapi")
#Default Calendar Folder
$MyDefCal = $MyNameSpace.GetDefaultFolder("olFolderCalendar")
#Folder or "Calendar" I want to add the Item to
$MySharedCal = $MyDefCal.Folders.Item("TestCal")
#Create the Calendar Item
$MyItem = $MySharedCal.Items.Add(1)
$MyItem.Body = "Test"
$MyItem.Subject = "This Is A Test"
$MyItem.Start = "03/01/2019"
$MyItem.AllDayEvent = 1
$MyItem.ReminderSet = 0
$MyItem.BusyStatus = 0
$MyItem.Save()
Thanks to Dimitry for the help.
Related
I work with Powershell and try to create a Telegram Bot.
Could somebody advise me please on how can I create an Inline Keyboard Button on the new row?
So, for example, I need to have two buttons on the first row and third button on the second row.
Like this:
Example
Here is a part of my code where I create buttons. It's working fine and all of them appears on one row.
$buttonsubcheck = #{ "text" = "Check status"; callback_data = "substatus" }
$buttonsubtrial = #{ "text" = "Request trial"; callback_data = "subtrial" }
$buttonsubback = #{ "text" = "Back"; callback_data = "back" }
$buttonssub = ($buttonsubcheck, $buttonsubtrial, $buttonsubback)
$buttonsubscription = #{"inline_keyboard" = #(, $buttonssub) } | ConvertTo-Json -Depth 5
So, in my case I need to move $buttonsubback button to the second row.
Tried Googling but didn't found solutions or any advises for Powershell
Solved. The corrected code below. Maybe it will help to smbd.
$buttonsubscription = #()
$buttonsubcheck = #{ "text" = "Check status"; callback_data = "substatus" }
$buttonsubtrial = #{ "text" = "Request trial"; callback_data = "subtrial" }
$buttonsubback = #{ "text" = "Back"; callback_data = "back" }
$row1 = #($buttonsubcheck, $buttonsubtrial)
$row2 = #($buttonsubback)
$buttonssub = ($row1, $row2)
$buttonsubscription = #{"inline_keyboard" = $buttonssub } | ConvertTo-Json -Depth 10
I'm using functions to create different WinForm elements; for example, RadioButtons inside of a GroupBox. I'm trying to pass in a variable representing the currently selected RadioButton that gets updated whenever a new one is selected.
function New-RadioButton
{
[OutputType([System.Windows.Forms.RadioButton])]
param
(
[int] $LocationX,
[int] $LocationY,
[string] $Label,
[System.Windows.Forms.RadioButton] $SelectedRB
)
$newButton = New-Object System.Windows.Forms.RadioButton
$newButton.Text = $Label
$newButton.AutoSize = $false
$newButton.Bounds = New-Object System.Drawing.Rectangle($LocationX, $LocationY, $RBWidth, $RBHeight)
$newButton.Add_CheckedChanged({
if($newButton.Checked) {
$SelectedRB = $newButton
}
}.GetNewClosure())
return $newButton
}
function New-GroupBox
{
[OutputType([System.Windows.Forms.GroupBox])]
param
(
[int] $LocationX,
[int] $LocationY,
[System.Windows.Forms.RadioButton] $SelectedRB
)
$rb1 = New-RadioButton $RBx $RB1y 'One' $SelectedRB
$rb2 = New-RadioButton $RBx $RB2y 'Two' $SelectedRB
$groupBox = New-Object System.Windows.Forms.GroupBox
$groupBox.AutoSize = $false
$groupBox.Bounds = New-Object System.Drawing.Rectangle($LocationX, $LocationY, $GBWidth, $GBHeight)
$groupBox.Controls.AddRange(#($rb1, $rb2))
return $groupBox
}
$Selection1 = New-Object System.Windows.Forms.RadioButton
$GroupBox1 = New-GroupBox $GB1x $GB1y $Selection1
$Selection2 = New-Object System.Windows.Forms.RadioButton
$GroupBox2 = New-GroupBox $GB2x $GB2y $Selection2
In specific, I'm using a script block inside of $newButton.Add_CheckChanged(), and trying to access the scope of the parent function to get and set the selection variable passed by reference. I'm not super proficient with PowerShell, I'm trying to write this like a lambda in C# and capture the scope of the parent. However, I know that this doesn't necessarily work in PowerShell - I've added {}.GetNewClosure(), but this only copies the current scope at creation time, not run-time.
I know that I could create script-wide variables (i.e. a script:$Selection or storing them in a hash table), but is there a solution that is agnostic to the name of the variable itself?
Edit: For reference, I'm using PowerShell 5.1.
Either I'm too stupid to google it properly or the problem is too obvious to solve.
I'm using a second small form to display a progressbar when running a function (Loading some information takes some time and this adds some nice responsiveness)
After the function finished and data is retreived, the progressbar-form is Closed with $formbar.Close()
If I call the function in the same instance again the progressbar wont show again because it was already disposed. How do I change that? I'd prefer not to "hide" the progressbar.
$formbar = New-Object System.Windows.Forms.Form
$progressBar1 = New-Object System.Windows.Forms.ProgressBar
$formbar.ControlBox = $false
$formbar.Size = '265,45'
$formbar.StartPosition = "CenterScreen"
$progressBar1.Style = "Continuous"
$progressBar1.ForeColor = "#009374"
$ProgressRange = 1..100
$ProgressMinMax = $ProgressRange | Measure -Minimum -Maximum
$progressBar1.Location = '0,0'
$progressBar1.Size = '250,30'
$progressBar1.Visible = $True
$progressBar1.Minimum = $ProgressMinMax.Minimum
$progressBar1.Maximum = $ProgressMinMax.Maximum
$progressBar1.Step = 10
$formbar.Controls.Add($progressBar1)
$formbar.Show()
Any ideas?
You need to re-create the whole form every time:
function New-ProgressBarForm {
$null = . {
$formbar = New-Object System.Windows.Forms.Form
$progressBar1 = New-Object System.Windows.Forms.ProgressBar
$formbar.ControlBox = $false
$formbar.Size = '265,45'
$formbar.StartPosition = "CenterScreen"
$progressBar1.Style = "Continuous"
$progressBar1.ForeColor = "#009374"
$ProgressRange = 1..100
$ProgressMinMax = $ProgressRange | Measure -Minimum -Maximum
$progressBar1.Location = '0,0'
$progressBar1.Size = '250,30'
$progressBar1.Visible = $True
$progressBar1.Minimum = $ProgressMinMax.Minimum
$progressBar1.Maximum = $ProgressMinMax.Maximum
$progressBar1.Step = 10
$formbar.Controls.Add($progressBar1)
}
return [pscustomobject]#{
Form = $formbar
ProgressBar = $progressBar1
}
}
Then call:
$progress = New-ProgressBarForm
$progress.Form.Show()
When you want to display it
Mathias answered the question, but you also asked why, so here's why.
When the user closes your form, either by the form being dismissed using the X or Close button, or when the Form.Close() method is closed, the following takes place:
When a form is closed, all resources created within the object are closed and the form is disposed. You can prevent the closing of a form at run time by handling the Closing event and setting the Cancel property of the CancelEventArgs passed as a parameter to your event handler. If the form you are closing is the startup form of your application, your application ends.
We can tell if its handles are still available by looking at the object's IsDisposed property.
#before showing
PS> $formBar.IsDisposed
False
PS> $formBar.Show()
PS> $formBar.IsDisposed
True
TLDR: it has to do with memory management. Once a form is shown and then closed, its gone from memory, but the variables it touched will forever remain in our hearts.
SCENARIO:
In my script, I create an object, add the common info, and then updated the sub info for each object in a loop and add that object to an array of objects.
My verbose shows that the values are correct in the object added to the array (reporting the last item in the array), but Export-Csv repeats the last object values.
I am able to resolve this if I create a new object each time. Reusing the same object repeats the last value, even though I can see it correct when I select * on the objects in the array. There must be something about the array object, such as a guid that is duplicated for the same object.
PowerShell 5.1 verified on Windows 7, Windows 2008R2, Windows 2010R2
SOLUTION:
Do not reuse an object when adding it to an array of objects.
OUTPUT:
#TYPE MyGpoSetting
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName","SubState","SubValue","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"
SCRIPT:
Add-Type -TypeDefinition #"
public struct MyGpoSetting
{
public string SetName;
public string SetCategory;
public string SetType;
public string SetState;
public string SetValue;
public string SetData;
public string SetNote;
public string SubName;
public string SubState;
public string SubValue;
public string GpoDomain;
public string GpoName;
public string GpoLinks;
public string GpoGuid;
}
"#
$aoMyGpoSetting = #();
$oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName = 'SetName';
$oMyGpoSetting.SetCategory = 'SetCategory';
$oMyGpoSetting.SetType = 'SetType';
$oMyGpoSetting.SetState = 'SetState';
$oMyGpoSetting.SetValue = 'SetValue';
$oMyGpoSetting.SetData = 'SetData';
$oMyGpoSetting.SetNote = 'SetNote';
$oMyGpoSetting.SubName = 'SubName1';
$oMyGpoSetting.SubState = 'SubState1';
$oMyGpoSetting.SubValue = 'SubValue1';
$oMyGpoSetting.GpoDomain = 'GpoDomain';
$oMyGpoSetting.GpoName = 'GpoName';
$oMyGpoSetting.GpoLinks = 'GpoLinks';
$oMyGpoSetting.GpoGuid = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
#--- $oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName = 'SetName';
$oMyGpoSetting.SetCategory = 'SetCategory';
$oMyGpoSetting.SetType = 'SetType';
$oMyGpoSetting.SetState = 'SetState';
$oMyGpoSetting.SetValue = 'SetValue';
$oMyGpoSetting.SetData = 'SetData';
$oMyGpoSetting.SetNote = 'SetNote';
$oMyGpoSetting.SubName = 'SubName2';
$oMyGpoSetting.SubState = 'SubState2';
$oMyGpoSetting.SubValue = 'SubValue2';
$oMyGpoSetting.GpoDomain = 'GpoDomain';
$oMyGpoSetting.GpoName = 'GpoName';
$oMyGpoSetting.GpoLinks = 'GpoLinks';
$oMyGpoSetting.GpoGuid = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
#--- $oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName = 'SetName';
$oMyGpoSetting.SetCategory = 'SetCategory';
$oMyGpoSetting.SetType = 'SetType';
$oMyGpoSetting.SetState = 'SetState';
$oMyGpoSetting.SetValue = 'SetValue';
$oMyGpoSetting.SetData = 'SetData';
$oMyGpoSetting.SetNote = 'SetNote';
$oMyGpoSetting.SubName = 'SubName3';
$oMyGpoSetting.SubState = 'SubState3';
$oMyGpoSetting.SubValue = 'SubValue3';
$oMyGpoSetting.GpoDomain = 'GpoDomain';
$oMyGpoSetting.GpoName = 'GpoName';
$oMyGpoSetting.GpoLinks = 'GpoLinks';
$oMyGpoSetting.GpoGuid = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
$aoMyGpoSetting | Export-Csv -Path 'c:\temp\export.csv' -Encoding 'ASCII';
This is working as expected. Adding the object to the array (+=) doesn't copy the object, but instead adds a reference/pointer to it in the next 'slot'. So in effect you are adding three references to the same object. It's like having 3 entries in your phonebook for your best friend:
John Smith - 01234 5678
Jonnie - 01234 5678
Smith, John - 01234 5678
Whichever one you call, gets you through to the exact same person.
Similarly, each time PowerShell displays an object from your array, it is actually going back to the same source object and showing it to you. That is why all of them have the same properties as the last one you added - they are in fact all that same one.
As you've discovered, creating a new object each time is the way to proceed.
I am trying to assign an array as a value to a dictionary entry as follows but its throwing exception.
$sd = New-Object 'System.Collections.Generic.SortedDictionary[int, string[]]'
$sd[0] = "Data1a", "asda";
Any idea?
Use cast to [string[]]:
$sd = New-Object 'System.Collections.Generic.SortedDictionary[int, string[]]'
$sd[0] = [string[]]("Data1a", "asda")
Another options is to change the dictionary value type to object[]:
$sd = New-Object 'System.Collections.Generic.SortedDictionary[int, object[]]'
$sd[0] = "Data1a", "asda"