How to compare Microsoft.Exchange.Common.ScheduleInterval with a datetime object? - powershell

I want find out if there is any Exchange database schedule running, or will run in the next few hours. However, I couldn't figure out how to compare the scheduleinterval object with a variable I created with get-date or (get-date).addhours(20)
The scheduleInterval I am looking at is
C:\>(get-mailboxdatabase | where {$_.name -like 'database'}).maintenanceschedule | Get-Member
TypeName: Microsoft.Exchange.Common.ScheduleInterval
Name MemberType Definition
---- ---------- ----------
CompareTo Method int CompareTo(System.Object value), int CompareTo(Microsoft.Exchange.Common.ScheduleInterval...
ConjointWith Method bool ConjointWith(Microsoft.Exchange.Common.ScheduleInterval other)
Contains Method bool Contains(Microsoft.Exchange.Common.WeekDayAndTime dt), bool Contains(System.DateTime dt...
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
Overlaps Method bool Overlaps(Microsoft.Exchange.Common.ScheduleInterval other)
ToString Method string ToString()
EndDay Property System.DayOfWeek EndDay {get;}
EndHour Property System.Int32 EndHour {get;}
EndMinute Property System.Int32 EndMinute {get;}
EndTime Property Microsoft.Exchange.Common.WeekDayAndTime EndTime {get;}
Length Property System.TimeSpan Length {get;}
StartDay Property System.DayOfWeek StartDay {get;}
StartHour Property System.Int32 StartHour {get;}
StartMinute Property System.Int32 StartMinute {get;}
StartTime Property Microsoft.Exchange.Common.WeekDayAndTime StartTime {get;}
Any help is much appreciated.
Thanks

Here a way to test if a job is running at the Get-Date value.
Maybe the comparison can be done casting starttime/endtime properties to [datetime] but I can't test, I'm just supposing..
$a = (get-mailboxdatabase | where {$_.name -like 'database'}).maintenanceschedule
$b = Get-date # you can add days to check events in the future
if ( $a.startday, $a.endday -contains $b.dayofweek)
{
if ( $a.starthour -le $b.hour -and $a.endhour -ge $b.hour)
{
if ( $a.startminute -le $b.minute -and $a.endminute -ge $b.minute)
{
Write-Host "Jod scheduled is running at this time!"
}
}
}

I wrote the following codes to convert the Microsoft.Exchange.Common.ScheduleInterval into an array of datetime objects. Hope someone can improve my codes...
$schedules=(get-mailboxdatabase|where {$_.name -like "dbname"}).maintenanceschedule
$curdatetime = get-date
$dowhash = #{"Monday"=1;"Tuesday"=2;"Wednesday"=3;"Thursday"=4; `
"Friday"=5;"Saturday"=6;"Sunday"=7}
$todaydow = $dowhash.get_item([string]$curdatetime.dayofweek)
$coming = #()
foreach ($schedule in $schedules) {
$dow = $dowhash.get_item([string]$schedule.startday)
$start = $curdatetime.adddays((($dow+7-$todaydow) % 7))
$startstr = "{0:yyyyMMdd}{1:00}{2:00}" `
-f $start,$schedule.starthour,$schedule.startminute
$dow = $dowhash.get_item([string]$schedule.endday)
$end = $curdatetime.adddays((($dow+7-$todaydow) % 7))
$endstr = "{0:yyyyMMdd}{1:00}{2:00}" `
-f $end,$schedule.endhour,$schedule.endminute
$coming+=,([datetime]::ParseExact($startstr,"yyyyMMddHHmm",$null), `
[datetime]::ParseExact($endstr,"yyyyMMddHHmm",$null) )
}
Thanks

Related

How to parse all given arguments in PowerShell

I want to create a loop function that looks like this:
function Loop { foreach ($File in Get-ChildItem | Select-Object -exp Name) { # Some command } }
It works perfectly fine for simple one-word commands, but it doesn't work for anything else. Of course, I need a way to parse all given arguments, but I don't know how. All documentations that I've been able to understand (I just started working with PowerShell about a week ago) don't seem to have an answer to this.
It would be great if someone could give me a solution to this problem.🙂
Like issuing several commands inside the loop?
#!/usr/bin/env powershell
function script:Loop {
foreach ($File in Get-ChildItem | Select-Object -ExpandProperty Name) {
##Some command
##another command
## a test
Write-Output -InputObject ('The current item is named {0}.' -f $file)
}
}
Loop
output
PS C:\Powershell\Scripts> . "c:\Powershell\Scripts\forloop.ps1"
The current item is named dchero.ps1.
The current item is named findinstaller.ps1.
The current item is named Untitled11.ps1.
The current item is named Untitled5.ps1.
The current item is named Untitled8.ps1.
However you don't really need to do the Select-Object -ExpandProperty Name because Get-ChildItem returns multiple properties for the objects it finds. You can see all of them by piping into Get-Member
PS C:\Powershell\Scripts> Get-ChildItem | Get-Member
TypeName: System.IO.FileInfo
Name MemberType Definition
---- ---------- ----------
Target AliasProperty Target = LinkTarget
LinkType CodeProperty System.String LinkType{get=GetLinkType;}
Mode CodeProperty System.String Mode{get=Mode;}
ModeWithoutHardLink CodeProperty System.String ModeWithoutHardLink{get=ModeWithoutHardLink;}
AppendText Method System.IO.StreamWriter AppendText()
CopyTo Method System.IO.FileInfo CopyTo(string destFileName), System.IO.FileInfo CopyTo(string destFileName, bool overwrite)
Create Method System.IO.FileStream Create()
CreateAsSymbolicLink Method void CreateAsSymbolicLink(string pathToTarget)
CreateText Method System.IO.StreamWriter CreateText()
Decrypt Method void Decrypt()
Delete Method void Delete()
Encrypt Method void Encrypt()
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetObjectData Method void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context), void ISerializab…
GetType Method type GetType()
InitializeLifetimeService Method System.Object InitializeLifetimeService()
MoveTo Method void MoveTo(string destFileName), void MoveTo(string destFileName, bool overwrite)
Open Method System.IO.FileStream Open(System.IO.FileMode mode), System.IO.FileStream Open(System.IO.FileMode mode, System.IO.FileAccess access), System.IO.F…
OpenRead Method System.IO.FileStream OpenRead()
OpenText Method System.IO.StreamReader OpenText()
OpenWrite Method System.IO.FileStream OpenWrite()
Refresh Method void Refresh()
Replace Method System.IO.FileInfo Replace(string destinationFileName, string destinationBackupFileName), System.IO.FileInfo Replace(string destinationFileName,…
ResolveLinkTarget Method System.IO.FileSystemInfo ResolveLinkTarget(bool returnFinalTarget)
ToString Method string ToString()
PSChildName NoteProperty string PSChildName=dchero.ps1
PSDrive NoteProperty PSDriveInfo PSDrive=C
PSIsContainer NoteProperty bool PSIsContainer=False
PSParentPath NoteProperty string PSParentPath=Microsoft.PowerShell.Core\FileSystem::C:\Powershell\Scripts
PSPath NoteProperty string PSPath=Microsoft.PowerShell.Core\FileSystem::C:\Powershell\Scripts\dchero.ps1
PSProvider NoteProperty ProviderInfo PSProvider=Microsoft.PowerShell.Core\FileSystem
Attributes Property System.IO.FileAttributes Attributes {get;set;}
CreationTime Property datetime CreationTime {get;set;}
CreationTimeUtc Property datetime CreationTimeUtc {get;set;}
Directory Property System.IO.DirectoryInfo Directory {get;}
DirectoryName Property string DirectoryName {get;}
Exists Property bool Exists {get;}
Extension Property string Extension {get;}
FullName Property string FullName {get;}
IsReadOnly Property bool IsReadOnly {get;set;}
LastAccessTime Property datetime LastAccessTime {get;set;}
LastAccessTimeUtc Property datetime LastAccessTimeUtc {get;set;}
LastWriteTime Property datetime LastWriteTime {get;set;}
LastWriteTimeUtc Property datetime LastWriteTimeUtc {get;set;}
Length Property long Length {get;}
LinkTarget Property string LinkTarget {get;}
Name Property string Name {get;}
BaseName ScriptProperty System.Object BaseName {get=if ($this.Extension.Length -gt 0){$this.Name.Remove($this.Name.Length - $this.Extension.Length)}else{$this.Name};}
VersionInfo ScriptProperty System.Object VersionInfo {get=[System.Diagnostics.FileVersionInfo]::GetVersionInfo($this.FullName);}
Now that we know what's available we can use them for our scripts.
Like so:
#!/usr/bin/env powershell
function script:Loop {
foreach ($File in (Get-ChildItem)) {
##Some command
##another command
## a test
Write-Output -InputObject ('The current item is named {0}.' -f $file.Name)
Write-Output -InputObject ('The current items size it {0}.' -f $file.Length)
Write-Output -InputObject ('The current items hashcode is {0}.
' -f $file.GetHashCode())
}
}
Loop
Output
PS C:\Powershell\Scripts> . "c:\Powershell\Scripts\forloop.ps1"
The current item is named dchero.ps1.
The current items size it 755.
The current items hashcode is 31624384.
The current item is named findinstaller.ps1.
The current items size it 236.
The current items hashcode is 55386574.
The current item is named forloop.ps1.
The current items size it 466.
The current items hashcode is 50677768.
Finally you can get fancy and make changes to the objects or test them.
#!/usr/bin/env powershell
function script:Loop {
foreach ($File in (Get-ChildItem)) {
## command /argument 1
if ($file.Name -like "*.ps1") {
<# Action to perform if the condition is true #>
Write-Output "We've got a Powershell script here!"
Write-Output "The script is named $file.name"
}
else {
Write-Output "This ain't a Powershell script."
Write-Output "It's named $file.name"
}
## command / arugment 2
$newname = $file.BaseName + "-modifiedbyscript" + $file.Extension
Rename-Item -Path $file.FullName -NewName $newname -WhatIf
}
}
Loop
This might be a hard guess, if it has nothing to do with what you're looking for let me know and I'll delete this answer. If it has something to do with what you're looking I can understand why it could be "hard to explain".
function ThisThing {
[CmdletBinding()]
param(
[parameter(Mandatory, ParameterSetName = 'Expression')]
[scriptblock] $Expression,
[parameter(Mandatory, ParameterSetName = 'Condition')]
[scriptblock] $Condition,
[parameter(Mandatory, ValueFromPipeline, Position = 0)]
[object[]] $InputObject
)
process {
if($PSCmdlet.ParameterSetName -eq 'Expression') {
if($MyInvocation.ExpectingInput) {
return & $Expression
}
$InputObject | & {
process {
& $Expression
}
}
}
else {
if($MyInvocation.ExpectingInput) {
return & { if(& $Condition) { $_ } }
}
$InputObject | & {
process {
if(& $Condition) { $_ }
}
}
}
}
}
A few examples to test the function:
ThisThing (0..10) -Expression {
[pscustomobject]#{
Input = $_
}
}
Get-ChildItem | ThisThing -Expression {
if($_.CreationTime -lt (Get-Date).AddDays(-30)) {
[pscustomobject]#{
CreationDate = $_.CreationTime
Path = $_.FullName
}
}
}
Get-Process | ThisThing -Condition { $_.Name -eq 'svchost' }
ThisThing (Get-Service) -Condition { $_.Status -eq 'Stopped' }

How to Export Clustered Scheduled Task

I try to export the XML of a Clustered Scheduled Task.
I search for the function as Export-ScheduledTask has for non Clustered Tasks.
Maybe there is a way via CIM when i execute a Get-ClusteredScheduledTask I get this.
But I have no idea how to query this
CimClass : Root/Microsoft/Windows/TaskScheduler:MSFT_ClusteredScheduledTask
CimInstanceProperties : {ClusterName, CurrentOwner, Resource, TaskDefinition...}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties
Edit1:
Get-Member
$task | Get-Member
TypeName: Microsoft.Management.Infrastructure.CimInstance#Root/Microsoft/Windows/TaskScheduler/MSFT_ClusteredScheduledTask
Name MemberType Definition
---- ---------- ----------
Clone Method System.Object ICloneable.Clone()
Dispose Method void Dispose(), void IDisposable.Dispose()
Equals Method bool Equals(System.Object obj)
GetCimSessionComputerName Method string GetCimSessionComputerName()
GetCimSessionInstanceId Method guid GetCimSessionInstanceId()
GetHashCode Method int GetHashCode()
GetObjectData Method void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context...
GetType Method type GetType()
ToString Method string ToString()
ClusterName Property string ClusterName {get;}
CurrentOwner Property string CurrentOwner {get;}
PSComputerName Property string PSComputerName {get;}
Resource Property string Resource {get;}
TaskDefinition Property CimInstance#Instance TaskDefinition {get;set;}
TaskName Property string TaskName {get;}
TaskType ScriptProperty System.Object TaskType {get=[Microsoft.PowerShell.Cmdletization.GeneratedTypes.ScheduledTask.ClusterTaskTypeEnum]($this.PSBas...
Try This
$TaskName = "Change_NTFS_permissions"
Get-ChildItem -Path ($env:SystemRoot +
'\System32\Tasks\Microsoft\Windows\Failover Clustering')
-File -Recurse | ? {$_.Name -like $TaskName} | Get-Content |
Out-File -FilePath ('C:\scripts\XML_Shedules' + '\' + $TaskName + '.xml')

Powershell Get-EventLog find event with the matching string in its message

I need to look through eventLog security ID 4648, and find the last time the user connected to the machine.
Currently this is my code:
$Values = invoke-command -ComputerName $ComputerName {Get-EventLog -LogName Security -InstanceID 4648 | Select-Object -ExpandProperty Message| ForEach-Object {if($_.Log -match "$String2"){
$_
Break }}}
$Values
The aim was to go through each log until a log where the message has the previously defined username is found, and then stop going through EventLog and return that log.
This is working well, except its not matching the correct log with the specified string.
Is there a way to improve how the matching works? So it actually finds the correct log with the specified user?
# Fill in the regex for the userName
$userName = "userName"
$Values = #(invoke-command -ComputerName $ComputerName {
Get-EventLog -LogName Security -InstanceID 4648 | Where-Object { $_.message -match $Using:userName } | Select-Object -First 1)
}
Your above sample won't work since message is of type string, therefore it doesn't have a Log property. Since we want $userName to be avaiable for read access on the remote machine we can use the $Using: syntax. To break the pipeline "iteration" I'm using Select-Object -First 1 which will return the first object passing the Where-Objectclause.
Resulting from that $Values points to a collection of (deserialized) objects (using the #() operator) of type:
TypeName: System.Diagnostics.EventLogEntry#Security/Microsoft-Windows-Security-Auditing/4648
Which means you can change the -First parameter to e.g. 10 and sort the result on the client machine:
$Values | sort TimeGenerated -Descending
If you want to know which properties are available you can use:
> $Values | gm
TypeName: System.Diagnostics.EventLogEntry#Security/Microsoft-Windows-Security-Auditing/4648
Name MemberType Definition
---- ---------- ----------
Disposed Event System.EventHandler Disposed(System.Object, System.EventArgs)
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
Dispose Method void Dispose(), void IDisposable.Dispose()
Equals Method bool Equals(System.Diagnostics.EventLogEntry otherEntry), bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetObjectData Method void ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
GetType Method type GetType()
InitializeLifetimeService Method System.Object InitializeLifetimeService()
ToString Method string ToString()
Category Property string Category {get;}
CategoryNumber Property int16 CategoryNumber {get;}
Container Property System.ComponentModel.IContainer Container {get;}
Data Property byte[] Data {get;}
EntryType Property System.Diagnostics.EventLogEntryType EntryType {get;}
Index Property int Index {get;}
InstanceId Property long InstanceId {get;}
MachineName Property string MachineName {get;}
Message Property string Message {get;}
ReplacementStrings Property string[] ReplacementStrings {get;}
Site Property System.ComponentModel.ISite Site {get;set;}
Source Property string Source {get;}
TimeGenerated Property datetime TimeGenerated {get;}
TimeWritten Property datetime TimeWritten {get;}
UserName Property string UserName {get;}
EventID ScriptProperty System.Object EventID {get=$this.get_EventID() -band 0xFFFF;}
Hope that helps.

Exporting dataRow to a csv

I have run a MySQL Query, which has given me a resultset that I can work with.
However, I now need to export it to a CSV file.
If I run
$result1 | export-csv "c:\path\to\csv.csv"
I get a file with a single entry in the first cell only:
#TYPE System.Int32
But there should be apx 6000 rows.
If I do
$result1 | Get-member
I get:
TypeName: System.Int32
Name MemberType Definition
---- ---------- ----------
CompareTo Method int CompareTo(System.Object value), int CompareTo(int value)
Equals Method bool Equals(System.Object obj), bool Equals(int obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
GetTypeCode Method System.TypeCode GetTypeCode()
ToString Method string ToString(), string ToString(string format), string ToString(System.IFormatP...
TypeName: System.Data.DataRow
Name MemberType Definition
---- ---------- ----------
AcceptChanges Method System.Void AcceptChanges()
BeginEdit Method System.Void BeginEdit()
CancelEdit Method System.Void CancelEdit()
ClearErrors Method System.Void ClearErrors()
Delete Method System.Void Delete()
EndEdit Method System.Void EndEdit()
Equals Method bool Equals(System.Object obj)
GetChildRows Method System.Data.DataRow[] GetChildRows(string relationName), System.D...
GetColumnError Method string GetColumnError(int columnIndex), string GetColumnError(str...
GetColumnsInError Method System.Data.DataColumn[] GetColumnsInError()
GetHashCode Method int GetHashCode()
GetParentRow Method System.Data.DataRow GetParentRow(string relationName), System.Dat...
GetParentRows Method System.Data.DataRow[] GetParentRows(string relationName), System....
GetType Method type GetType()
HasVersion Method bool HasVersion(System.Data.DataRowVersion version)
IsNull Method bool IsNull(int columnIndex), bool IsNull(string columnName), boo...
RejectChanges Method System.Void RejectChanges()
SetAdded Method System.Void SetAdded()
SetColumnError Method System.Void SetColumnError(int columnIndex, string error), System...
SetModified Method System.Void SetModified()
SetParentRow Method System.Void SetParentRow(System.Data.DataRow parentRow), System.V...
ToString Method string ToString()
Item ParameterizedProperty System.Object Item(int columnIndex) {get;set;}, System.Object Ite...
CJ Property System.UInt64 CustomerJobId {get;set;}
End Property System.DateTime Endtime {get;set;}
Name Property System.String Engineer {get;set;}
JN Property System.String Jobname {get;set;}
Start Property System.DateTime Starttime {get;set;}
What's the correct way to convert this to a CSV file?
write-host $result1 gives me data similar to the below:
CJ :
JN :
Name : Mr Smith
Start :
End :
CJ : 987654321
JN :
Name : Mr Jones
Starttime : 29/09/2015 08:00:00
Endtime : 29/09/2015 08:30:00
I have found a way to make this work, by creating a PSObject, and then converting that to CSV.
$a = 0
$data = #()
foreach($res in $result1)
{
if($a -eq 0)
{
#Do Nothing
}
else
{
$cj = $res.CJ
$jn = $res.JN
$en = $res.Name
$st = $res.Start
$et = $res.End
#write-host "$cj,$jn,$en,$st,$et"
$row = New-Object PSObject
$row | Add-Member -MemberType NoteProperty -Name "CJ" -Value $cj -force
$row | Add-Member -MemberType NoteProperty -Name "JN" -Value $jn -force
$row | Add-Member -MemberType NoteProperty -Name "Name" -Value $en -force
$row | Add-Member -MemberType NoteProperty -Name "Start" -Value $st -force
$row | Add-Member -MemberType NoteProperty -Name "End" -Value $et -force
$data += $row
}
$a++
}
$data | Export-Csv "c:\path\to\csv.csv" -NoTypeInformation

powershell missing member methods in array

I have (yet another) powershell query. I have an array in powershell which i need to use the remove() and split commands on.
Normally you set an array (or variable) and the above methods exist. On the below $csv2 array both methods are missing, i have checked using the get-member cmd.
How can i go about using remove to get rid of lines with nan. Also how do i split the columns into two different variables. at the moment each element of the array displays one line, for each line i need to convert it into two variables, one for each column.
timestamp Utilization
--------- -----------
1276505880 2.0763250000e+00
1276505890 1.7487730000e+00
1276505900 1.6906890000e+00
1276505910 1.7972880000e+00
1276505920 1.8141900000e+00
1276505930 nan
1276505940 nan
1276505950 0.0000000000e+00
$SystemStats = (Get-F5.iControl).SystemStatistics
$report = "c:\snmp\data" + $gObj + ".csv"
### Allocate a new Query Object and add the inputs needed
$Query = New-Object -TypeName iControl.SystemStatisticsPerformanceStatisticQuery
$Query.object_name = $i
$Query.start_time = $startTime
$Query.end_time = 0
$Query.interval = $interval
$Query.maximum_rows = 0
### Make method call passing in an array of size one with the specified query
$ReportData = $SystemStats.get_performance_graph_csv_statistics( (,$Query) )
### Allocate a new encoder and turn the byte array into a string
$ASCII = New-Object -TypeName System.Text.ASCIIEncoding
$csvdata = $ASCII.GetString($ReportData[0].statistic_data)
$csv2 = convertFrom-CSV $csvdata
$csv2
There is no Remove or Split method on .NET's Array type, or added by the PowerShell wrapper around an Array instance. This is quite easy to show:
PS[64bit] E:\> $a = 1,2,3,4,5
PS[64bit] E:\> $a.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS[64bit] E:\> Get-Member -InputObject $a
TypeName: System.Object[]
Name MemberType Definition
---- ---------- ----------
Count AliasProperty Count = Length
Address Method System.Object&, mscorlib, Version=2.0.0.0, Culture=neutral, PublicK...
Clone Method System.Object Clone()
CopyTo Method System.Void CopyTo(array array, int index), System.Void CopyTo(arra...
Equals Method bool Equals(System.Object obj)
Get Method System.Object Get(int )
GetEnumerator Method System.Collections.IEnumerator GetEnumerator()
GetHashCode Method int GetHashCode()
GetLength Method int GetLength(int dimension)
GetLongLength Method long GetLongLength(int dimension)
GetLowerBound Method int GetLowerBound(int dimension)
GetType Method type GetType()
GetUpperBound Method int GetUpperBound(int dimension)
GetValue Method System.Object GetValue(Params int[] indices), System.Object GetValu...
Initialize Method System.Void Initialize()
Set Method System.Void Set(int , System.Object )
SetValue Method System.Void SetValue(System.Object value, int index), System.Void S...
ToString Method string ToString()
IsFixedSize Property System.Boolean IsFixedSize {get;}
IsReadOnly Property System.Boolean IsReadOnly {get;}
IsSynchronized Property System.Boolean IsSynchronized {get;}
Length Property System.Int32 Length {get;}
LongLength Property System.Int64 LongLength {get;}
Rank Property System.Int32 Rank {get;}
Arrays in .NET, and PowerShell, are fixed size. To remove an element you need to copy all but the element to be removed, in PSH this can be done with Where-Object:
$newArray = $oldArray | Where-Object {some-condition-on-$_}
Similarly Select-Object with -First and -Skip parameters can be used to select elements before or after (resp3ectively) an index.
NB System.Array does implement System.Collections.ILst but the explicit implementation of IList.Remove just throws a NotImplementedException.