bin/SnsPsScriptsMonitoring.dll-Help.xml

<?xml version="1.0" encoding="utf-8"?>
<helpItems schema="maml" xmlns="http://msh">
  <!-- Cmdlet: Initialize-SnsModuleState -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Initialize-SnsModuleState</command:name>
      <command:verb>Initialize</command:verb>
      <command:noun>SnsModuleState</command:noun>
      <maml:description>
        <maml:para>Verifies The Monitoring DataBase Existence And Creates It If Needed.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Verifies The Monitoring DataBase Existence And Creates It If Needed.</maml:para>
      <maml:para>The CmdLet Is Hidden For The User And Run Once On The PowerShell Module Load.</maml:para>
      <maml:para>The SnsPsScriptsMonitoring PowerShell Module Uses An SQLite Serverless DataBase To Store The Required Information About The Enabled For Monitoring Scripts. It Requires The Monitoring DataBase To Be Stored Somewhere Permanently Regardless Of Location Where The PowerShell Module Is Installed. The PowerShell Modules Are Installed In Different Locations Depending On The Installation Scope. And All Those Locations Are Protected Which Means That If The User Is Running The Module In Not Elevated Mode Will Be Not Able To Write Into The Monitoring DataBase. The Most Appropriate Location In Such Scenarios Is To Make A Subfolder In "ProgramData" Folder Which Is Enumerated By .NET And There Is No Need To Hardcode The Path To The DataBase. The "ProgramData" Folder Itself Is Protected, However The User Created Folders Inside Are Not. From That Perspective The Monitoring DataBase Is Created In:</maml:para>
      <maml:para>"%ProgramData%\SnsPsScriptsMonitoring\SnsScrMon.db"</maml:para>
      <maml:para>The Monitoring DataBase Used Is A Simple One With A Single Table. However The Loading Checks Are Quite Complete And Heavy. If All Of Them Are Performed Could Lead To Unnecessary Decrease Of The Monitored Scripts Performance. The DataBase Verification Checks And DataBase Maintenance Tasks Are Distinguished Into 3 Groups. The Monitoring DataBase Is Verified About:</maml:para>
      <maml:para>-- DataBase Folder Enumeration. Because The ProgramData Folder Is Managed By The OS Its Location Could Be Modified. Therefore The DataBase And DataBase Folder Paths Are Considered As Dynamic And Their Values Have To Be Enumerated. The Enumeration Happens Once On The Module Lode. In Case Something Is Modified After The Module Load Will Lead To Errors As Long As The Module Will Not Be Able To Access Its Own DataBase.</maml:para>
      <maml:para>-- DataBase File Path Enumeration. The Enumeration Happens Just Once At The Module Load.</maml:para>
      <maml:para>-- The Existence Of The DataBase File And Its LastWriteTime. In Case The DataBase Does Not Exists Or The LastWriteTime Of The DataBase File Is Not In The Current Date, All DataBase Verification Checks Are Enabled. The LastWriteTime Is Taken Only When The DataBase File Exists To Prevent Errors. This Evaluation Is Always Made. Therefore If The Module Is Loaded And Left In PowerShell Process For Long Time On The First Run Of Any Command After The Date Is Changed The Module Will Do The Complete Set Of Verifications. This Evaluation Happens Before Each CmdLet Run In Its Begin Method.</maml:para>
      <maml:para>-- The Existence Of The DataBase Folder. In Case The Folder Does Not Exists It Is Created. This Requires The First PS Module Load To Be Made In Elevated Mode. This Verification Is Part Of The First Group Of Checks Named Basic Checks.</maml:para>
      <maml:para>-- The NTFS Permissions Of The DataBase Folder. "Full Control" To Local Users Group Is Verified And If Needed Is Granted. In Order Granting To Work The Module Have To Be Imported In Elevated PowerShell Process. Because The Creation Of The Folder Requires Elevated Right After The Creation Access Rights Are Immediately Granted And Remains Afterward. Therefore Elevated Mode Is Required Only On The First Module Import. This Is Part Of The Basic Checks Group.</maml:para>
      <maml:para>-- The Existence Of The DataBase File. In Case The DataBase Is Missing The Module Creates One. This Is Part Of The Basic Checks.</maml:para>
      <maml:para>-- The CmdLet Verifies The Existence And The Schema Of The Monitoring Table Within The Monitoring DataBase. In Case The Table Is Missing New One Is Created. In Case The Table Is There But The Table Schema Does Not Match The Module Requirements, A DataBase Backup Is Made And The Invalid Table Is Deleted, Then New Table Is Created With The Correct Schema. This Task Is Part Of The Basic Verifications.</maml:para>
      <maml:para>-- The Existence Of Any Other Than The Monitoring DataBase Files In The DataBase Folder. In Case Such Files Exist They Are Deleted. Any Monitoring DataBase Backup Files Existence Is Tolerated For 61 Days. This Is Part Of The Next Group Of Task Named Advanced Verifications.</maml:para>
      <maml:para>-- The Existence Of Any Nested Folders. The Module Requires And Creates A Single DataBase File, Except In The Cases When DB Backup Is Made. It Does Not Create Any Subfolders Within The DataBase Folder. If Any Are Detected They Are Deleted Immediately. This Task Is Part Of The Advanced Verifications Group.</maml:para>
      <maml:para>-- The Tables Located Inside The DataBase. The SnsPsScriptsMonitoring PowerShell Module Uses A Single Table Within Its Own DataBase. In Case Any Other Tables Appear Would Mean That The DataBase Is Modified By The User Using 3rd Party Tools. Such Tables Are Deleted. This Task Is Part Of The Advanced Verifications Group.</maml:para>
      <maml:para>-- The CmdLet Verifies The Existence And The Schema Of The Indexes Associated With The Monitoring Table Within The Monitoring DataBase. In Case The Indexes Are Missing New Ones Are Created. This Task Is Part Of The Advanced Verifications Group.</maml:para>
      <maml:para>-- The CmdLet Creates A Test Monitoring Entry, Verify Its Creation, Then Delete The Test Entry And Verifies The Deletion. This To Be Confirmed Before The Work Is Started That The User Have The Required Access Rights To The Monitoring DataBase. This Task Is Part Of The Advanced Verifications Group.</maml:para>
      <maml:para>-- The CmdLet Verifies About The Existence Of Outdated Entries Related With Scripts Not Being Monitored For More Than 14 Days And Deletes Them. Whenever Deletion Of Outdated Entries Is Made, The CmdLet Defragments And Compacts The Monitoring DataBase To Release The White Space To The Operating System. This Task Is In A Group Of Its Own Named Delete Outdated Entries.</maml:para>
      <maml:para>Once Verifications From A Specific Group Are Successfully Completed, They Are Not Performed Again In The Same PowerShell Session, Except If The Session Is Long Enough To Spread Across Dates. Which Means For Example Starting A Session At 11PM And Leave The Session Open On The Next Command Run In 1 AM All The Verifications Will Be Made From Scratch.</maml:para>
      <maml:para>The Verification Tasks Are Executed When:</maml:para>
      <maml:para>-- It Is The First PowerShell Module Load Or Run Of A Command From The Module For The First Time On The Date. In That Case All 3 Groups Of Verification Tasks Will Be Run.</maml:para>
      <maml:para>-- The PowerShell Module Is Loaded Interactively And The Calling Of The Module IS Not Part Of Script Or Automation. In That Case All The 3 Groups Of Verification Tasks Will Run.</maml:para>
      <maml:para>-- The PowerShell Module Is Loaded With Call From A Script Or With Call From A Not Interactive Process. Then Will Be Executed The Verification Tasks From The Basic Group.</maml:para>
      <maml:para>-- A Command Is Run To Enable Or Disabled The Monitoring Of A Script. Then Will Be Executed The Basic Verification Tasks If They Are Not Already Made.</maml:para>
      <maml:para>-- A Command Is Run To Get The Monitored Scripts. Then Will Be Executed Only The Verification Groups Which Are Not Already Completed. Lets For Example Assume The Module Is Loaded With The Monitoring Script Run On A Schedule As A Service. During The Module Load The Basic Tasks Will Complete. Then The Script Call Get-SnsScriptMonitoringEntry CmdLet. Before The CmdLet To Do Its Job Within Its Begin Method Will Call The DataBase Verifications Method To Complete All The Verifications. Since The Basic Tasks Are Already Completed During The Module Import, Only The Advanced And Delete Outdated Entries Groups Will Run. On The Consequent Run Of The Get-SnsScriptMonitoringEntry CmdLet No Verifications Will Be Made Because All 3 Groups Are Completed. On Consequent Enable Or Disable Commands No Verifications Will Be Made Because The Basic Verifications Are Already Completed. Unless The Consequent Runs Of The CmdLets Are In The Next Date.</maml:para>
      <maml:para>The Monitoring Table In The Monitoring DataBase Have Schema Closely Related With The Desired Monitoring Logic. The Table Have The Following DataBase Schema:</maml:para>
      <maml:para>CREATE TABLE IF NOT EXISTS [Monitor]</maml:para>
      <maml:para>(</maml:para>
      <maml:para>[Machine] VARCHAR NOT NULL,</maml:para>
      <maml:para>[Directory] VARCHAR NOT NULL,</maml:para>
      <maml:para>[Script] VARCHAR NULL,</maml:para>
      <maml:para>[MonitoredFile] VARCHAR PRIMARY KEY UNIQUE NOT NULL,</maml:para>
      <maml:para>[Task] VARCHAR NULL,</maml:para>
      <maml:para>[Pid] INTEGER NULL,</maml:para>
      <maml:para>[Threshold] INTEGER NOT NULL,</maml:para>
      <maml:para>[Enabled] LONG NOT NULL,</maml:para>
      <maml:para>[Disabled] LONG NOT NULL DEFAULT (0)</maml:para>
      <maml:para>);</maml:para>
      <maml:para>CREATE INDEX IF NOT EXISTS [ind_Monitor_Machine] ON [Monitor] ( [Machine] );</maml:para>
      <maml:para>CREATE INDEX IF NOT EXISTS [ind_Monitor_Directory] ON [Monitor] ( [Directory] );</maml:para>
      <maml:para>CREATE INDEX IF NOT EXISTS [ind_Monitor_Script] ON [Monitor] ( [Script] );</maml:para>
      <maml:para>CREATE INDEX IF NOT EXISTS [ind_Monitor_MonitoredFile] ON [Monitor] ( [MonitoredFile] );</maml:para>
      <maml:para>CREATE INDEX IF NOT EXISTS [ind_Monitor_Task] ON [Monitor] ( [Task] );</maml:para>
      <maml:para>CREATE INDEX IF NOT EXISTS [ind_Monitor_Pid] ON [Monitor] ( [Pid] );</maml:para>
      <maml:para>CREATE INDEX IF NOT EXISTS [ind_Monitor_Threshold] ON [Monitor] ( [Threshold] );</maml:para>
      <maml:para>CREATE INDEX IF NOT EXISTS [ind_Monitor_Enabled] ON [Monitor] ( [Enabled] );</maml:para>
      <maml:para>CREATE INDEX IF NOT EXISTS [ind_Monitor_Disabled] ON [Monitor] ( [Disabled] );</maml:para>
      <maml:para>The "MonitoredFile" Column Is Used To Specify A Transcript Or Log File Produced By The Monitored Script Which Is Regularly Updated. The Script That Produces This File Is Considered As Failed Whenever The File Was Not Updated For Period Specified Within "Threshold" Column Or Its Process Is No Longer Running.</maml:para>
      <maml:para>The "Task" And "Pid" Columns Are Used To Store Information About The Monitored Script. They Are The Input Needed For The Feature Which Stops The Failed Scripts Processes And Restarts Their Tasks. This Information Is Not Required As Long As The Restarting Feature Is Not Essential For The Module Normal Operation. However Without That Information The Restarting Feature Will Not Work.</maml:para>
      <maml:para>The "Directory", "Script" And "Task" Columns Are Used By The Feature Which Automatically Disable From Monitoring The Failed Scripts Entries, Whenever New Instance Of The Same Script Is Enabled For Monitoring. An Example Will Be More Appropriate Explanation. If We Have A Script That Produces Different Transcript File On Each Run And It Is Executed With A Scheduled Task. When The Script Fail Will Not Disable Its Own Entry. Lets Assume The CmdLet For Monitoring Detect That And Restarts The Script. Then The Script Will Produce New Transcript File Within The Same Folder And It Is Started With The Same Scheduled Task. In That Case The Monitoring CmdLet Have To Take Care And Disable The Entry Related With The Failed Instance Since The New Instance Is Running. For Monitoring Entries With Missing The Above Information, This Auto Monitoring Disable Feature Will Not Work. When This Happen The Failed Monitoring Entry Will Remain And The Monitored Script Will Continue To Be Reported As Failed Until A Human Manually Disable The Entry Using Disable-SnsScriptMonitoring CmdLet.</maml:para>
      <maml:para>"Enabled" And "Disabled" - The "Enabled" Column Contains The FileTime When The Monitoring Entry Was Created And The Monitored File Enabled For Monitoring. The "Disabled" Column Shall Contain The FileTime When The Entry Was Disabled And The Script Is No Longer Monitored.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Initialize-SnsModuleState</maml:name>
        <!-- Parameter: DeleteOutdatedEntries -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DeleteOutdatedEntries</maml:name>
          <maml:description>
            <maml:para>Specifies To The CmdLet To Delete The Outdated Monitoring Entries. As Outdated Monitoring Entries Are Considered Ones Related With Scripts Not Being Monitored For More Than 31 Days.</maml:para>
            <maml:para>Deletion Of The Outdated Entries Automatically Enable The DataBase Defragmentation And Compacting The DataBase File To Release The Whitespace To The Operating System.</maml:para>
            <maml:para>In Case There Are No Deleted Outdated Monitoring Entries, DataBase Defragmentation And Compacting Is Not Made.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: DeleteOutdatedEntries -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>DeleteOutdatedEntries</maml:name>
        <maml:description>
          <maml:para>Specifies To The CmdLet To Delete The Outdated Monitoring Entries. As Outdated Monitoring Entries Are Considered Ones Related With Scripts Not Being Monitored For More Than 31 Days.</maml:para>
          <maml:para>Deletion Of The Outdated Entries Automatically Enable The DataBase Defragmentation And Compacting The DataBase File To Release The Whitespace To The Operating System.</maml:para>
          <maml:para>In Case There Are No Deleted Outdated Monitoring Entries, DataBase Defragmentation And Compacting Is Not Made.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes />
    <command:returnValues />
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>Initialize-SnsModuleState -DeleteOutdatedEntries;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsScriptsMonitoring - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsScriptsMonitoring</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsScriptsMonitoring/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Disable-SnsScriptMonitoring -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Disable-SnsScriptMonitoring</command:name>
      <command:verb>Disable</command:verb>
      <command:noun>SnsScriptMonitoring</command:noun>
      <maml:description>
        <maml:para>Disables A Monitoring Entry In The Monitoring DataBase.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Disables A Monitoring Entry In The Monitoring DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Whenever A Script Fails It Either Have Its Process Stuck Without Being Able To Continue Further Or Its Process Completely Stop. In Both Cases The Script Cannot Notify About The Failure Nor Continue Further. From That Perspective Whenever We Have Automation Scripts Doing Business Critical Tasks We Need To Monitor Their Running Using Another Script Named Here Monitoring Script.</maml:para>
      <maml:para>Detecting A Failed Script Is Relatively Easy, Whenever We Have Failed Script Its Process Stops And No Longer Could Be Enumerated With The Machines Processes. A Monitoring Script Could Detect The Failure And Either Report Or Take Actions. However That's Not The Case With The Stuck Scripts. Their Processes Are Still Running And Just Doing Nothing. A Monitoring Script Could Be Easily Mistaken That A Stuck Script Is Running As Usual. Monitoring Of Stuck Scripts Can Be Achieved Via Using Of Transcript Files By The Monitored Scripts Which To Be Updated Regularly. The Monitored Script Could Check The LastWriteTime Of Those Transcript Files And Based On A Threshold Could Decide Whether Specific Monitored Script Is Stuck Or Continue To Be Updated.</maml:para>
      <maml:para>The Module Requires The Monitored Scripts To Write Output Regularly On Either Transcript Or Log File, Named Here Monitored File. From Within The Monitored Script Must Be Created A Monitoring Entry Kept In A Monitoring DataBase About The Monitored File Using Enable-SnsScriptMonitoring CmdLet. At The End Of The Monitored Script Running It Must Run Disable-SnsScriptMonitoring To Indicate It Is Completed Successfully And No Longer Needs To Be Monitored. Whenever Disabling From Monitoring Is Omitted The Module Still Can Identify Successfully Completed Scripts Using The Monitored Script Exit Code Supplied To Its Scheduled Task. In Order This To Work As Expected The Monitoring Entry Must Have The Correct Scheduled Task Path And Access Rights To Verify Whether Its State Is Ready And The Last Exit Code Is 0 (Exit Without Failures). Additionally The Monitored Script Must Supply That Information To Its Task. Whenever The Disabling From Monitoring Is Omitted Could Lead To Unexpected Results.</maml:para>
      <maml:para>We Use Get-SnsScriptMonitoringEntry CmdLet From Within The Monitoring Script To Monitor The Monitored Scripts. The CmdLet Is Capable To Automatically Restart The Failed Scripts, If Needed And The Prerequisites For That Are Met.</maml:para>
      <maml:para>Because The Monitored Script Could Be Stuck Or Failed We Need Additional Script Executed On A Schedule To Run Get-SnsScriptMonitoringEntry In Order To Monitor The Monitored Scripts Operation. The Monitoring Script Must Be Reliable And Not Resource Intensive. The Reliability And Performance Considerations Are The Main Reason This Module To Be Developed As Binary PowerShell Module.</maml:para>
      <maml:para>The "SnsPsScriptsMonitoring" PowerShell Module Contains All The CmdLets Required For Enable Monitoring, Disable Monitoring, And Being Monitored By A Dedicated Monitoring Script. All The Needed CmdLets Are In One Place And There Is No Monitoring And Monitoring Agent PowerShell Modules.</maml:para>
      <maml:para>The Module Requires The Monitored Scripts To Comply With The Following Requirements:</maml:para>
      <maml:para>- The Monitored Scripts Must Update Periodically Transcript Or Log Files. Whenever Those Files Are Not Modified For Specified Period Of Time Their Scripts Are Considered As Stuck. The Monitoring CmdLet Does Not Read The Content Of The Transcript Files. We Need The Monitoring Processes To Be Fast As Possible. Reading File Content Is Not Among The Operations Considered As Fast. The Account That Running The Get-SnsScriptMonitoringEntry CmdLet Requires NTFS Permissions Over The Monitored Files To Read Their LastWriteTime.</maml:para>
      <maml:para>- To Identify Failed Script Processes The Get-SnsScriptMonitoringEntry CmdLet Verifies Whether The Script Process Is Still Running. This Requires The Correct Process ID Of The Script Process To Be Present In The Monitoring Entry. The Process ID's Are Assigned By The Operating System Dynamically, Therefore They Cannot Be Specified At The Time When The Monitored Script Is Written And Provided To Enable-SnsScriptMonitoring CmdLet. However The PowerShell Can Dynamically Identify Its Own Process, And The Enable-SnsScriptMonitoring CmdLet Do So Dynamically. Therefore It Is Mandatory It To Be Run From The Monitored Script. In That Way In The Monitoring Entry Will Be Present The Correct Process ID Of The Monitored Script Process.</maml:para>
      <maml:para>Get-SnsScriptMonitoringEntry Can Identify The Properly Running Scripts. Depending On The Specified Parameters And The Information Available In The Monitoring Entry Could Action The Enumerated Failed And Or Stuck Scripts Via Stopping The Monitored Script Process And Restarting Of The Monitored Script Scheduled Task. To Ensure This Feature Is Available Make Sure As Much As Possible Information Is Provided When The Monitored Script Is Enabled For Monitoring.</maml:para>
      <maml:para>The CmdLets In This Module Can Work Only Locally Which Means That The Monitored Scripts And The Monitoring Script Must Run On The Same Machine.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The SnsPsScriptsMonitoring Uses An SQLite V3 Serverless DataBase To Keep Track Of The Monitored Scripts Information. When The PowerShell Module Is Loaded For The First Time It Automatically Creates The Monitoring DataBase At The Following Location:</maml:para>
      <maml:para>"%ProgramData%\SnsPsScriptsMonitoring\SnsScrMon.db"</maml:para>
      <maml:para>Because Creation Of Folders And Files Within That Folder Requires Elevated Access Rights The First Load Of The Module Must Be In Elevated PowerShell Process. The Consequent Loads Of The Module Does not Require Elevated Mode, Except Specific Feature Requires It, And The Feature Itself Is Required. For Example Restart Of The Failed Scripts Requires The Monitored Script To Be Run In Elevated Mode, But The User Might Need The Failures To Be Reported And Not Actioned. In That Case There Is No Point To Run The Monitoring Script In Elevated Mode.</maml:para>
      <maml:para>The Information Kept In The Monitoring DataBase Is: "Machine", "Directory", "Script", "MonitoredFile", "Task", "Pid", "Threshold", "Enabled" And "Disabled".</maml:para>
      <maml:para>"Machine" Is The Fully Qualified Domain Name (FQDN) Of The Machine Where The Monitored Script Is Running. This Is Automatically Enumerated By Enable-SnsScriptMonitoring CmdLet And No User Input Is Possible.</maml:para>
      <maml:para>"Directory" Is The Folder Where The Monitored File Reside. This Information Is Automatically Enumerated From The Specified Monitored File And No User Input Is Possible.</maml:para>
      <maml:para>"Script" Is The .PS1 FileName Of The Monitored Script. This Information Is Automatically Enumerated. In Order The Enumeration To Work Correctly, Enable-SnsScriptMonitoring CmdLet Must Be Run From The Monitored Script. The "Script" Name Is Used For RestartFailed Feature, And For The Automatic Disabling From Monitoring Of Failed Scripts When The Failed Script Is Restarted And Newer Monitoring Entry Is Created About New Monitoring File Of The Same Script. "Script" Is Not Mandatory However When The Value Is Missing Or Incorrect Those Features Will Not Work. In Case The CmdLet Is Included In Scripts PowerShell Modules, The CmdLet Will Wrongly Identify The Script Module File As Monitored Script, From That Perspective The CmdLet Must Be Called From The Monitored Script Main .PS1 File.</maml:para>
      <maml:para>"MonitoredFile" Is The Full Absolute UNC Path To The Specified Monitored File. This Must Be Explicitly Specified To Enable-SnsScriptMonitoring CmdLet. There Is No Automatic Enumeration.</maml:para>
      <maml:para>"Task" Is The Full Path Of The Monitored Script Windows Scheduled Task. This Information Is Not Mandatory However Without It No Automatic Restart Of The Failed Scripts Is Possible. The Module Can Auto Enumerate It With Limited Success. It Is Preferable That "Task" Is Explicitly Specified To Enable-SnsScriptMonitoring CmdLet.</maml:para>
      <maml:para>"Pid" Is The Process ID Of The Script's PowerShell Process. This Is Automatically Enumerated. In Order The Auto Enumeration To Identify The Correct Process, The Enable-SnsScriptMonitoring Must Be Run From The Monitored Script.</maml:para>
      <maml:para>"Threshold" Is The Time Interval In Minutes About Inactivity Of The Monitored Script Used As A Threshold To Identify Whether It Is Stuck. The Inactivity Is Measured Via Reading The LastWriteTime Of The Script Transcript Or Log File Specified As Monitored File. For The Correct Identifying Please Make Shure That The Monitored Script Updates Periodically The Specified Monitored File. The Threshold Shall Be Considered Carefully Depending On The Intervals That The Monitored File Is Updated. Wrong Threshold Could Cause False Positives And Working Script To Be Stopped And Restarted In The Middle Of A Heavy Task.</maml:para>
      <maml:para>"Enabled" Is The DateTime When The Monitoring Entry Is Created, Converted To FileTime.</maml:para>
      <maml:para>"Disabled" Is The DateTime When The Monitoring Entry Is Disabled And The Monitored Script Stopped To Be Monitored, Converted To FileTime. Disabling From Monitoring Might Happen In Three Scenarios:</maml:para>
      <maml:para></maml:para>
      <maml:para>-- When The Monitored Script Finish Successfully. This Requires At The End Of The Monitored Script Have To Be Called Disable-SnsScriptMonitoring CmdLet. The CmdLet Updates The Monitoring Entry Via Specifying The Current DateTime Converted To FileTime In "Disabled" Column Of The Monitoring Entry. From That Moment On The Monitored File Updates And The Script Process Running Are No Longer Evaluated.</maml:para>
      <maml:para>-- When The Monitored Script Fail And AutoDisable Feature Is Used And New Instance Of The Monitoring Script Is Started And Enabled For Monitoring. Then The Failed Old Instance Will Be Disabled From Monitoring. The Way The Failed Script Is Restarted Does Not Make Any Difference. This Feature Will Work As Long As The Monitored Entry Have The Correct Values In "Script", "Directory" And "Task" Properties. It Is Not Related With RestartFailed Feature.</maml:para>
      <maml:para>-- When The User Runs Manually Disable-SnsScriptMonitoring CmdLet. This Is The Only Option To Stop The Reports For Failed Scripts That Did Not Disabled Themselves From Monitoring And The Prerequisites For AutoDisable Feature Are Not Met. For Example When The Scheduled Task Is Not Provided And Its Enumeration Failed.</maml:para>
      <maml:para>During The Module Load The Outdated Monitoring Entries Are Deleted And The Monitoring Database Is Defragmented And Shrank To Release Its White Space To The Operating System. For Outdated Entries Are Considered The Ones Which Are Disabled More Than 14 Days Ago. Enabled Entries Are Never Threated As Outdated Regardless Of Their Age.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Disable-SnsScriptMonitoring</maml:name>
        <!-- Parameter: Path -->
        <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
          <maml:name>Path</maml:name>
          <maml:description>
            <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: PassThru -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>PassThru</maml:name>
          <maml:description>
            <maml:para>Specifies To The CmdLet To Revert A MonitoringEntry Object.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: Path -->
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>Path</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>FilePath</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          <maml:para>This is an alias of the Path parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>TranscriptFile</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          <maml:para>This is an alias of the Path parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>LogFile</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          <maml:para>This is an alias of the Path parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: PassThru -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>PassThru</maml:name>
        <maml:description>
          <maml:para>Specifies To The CmdLet To Revert A MonitoringEntry Object.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes />
    <command:returnValues>
      <!-- OutputType: MonitoringEntry -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsPsScriptsMonitoring.MonitoringEntry</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>Disable-SnsScriptMonitoring -Path "C:\Transcript.txt";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsPsScriptsMonitoring.MonitoringEntry]$objEntry = Disable-SnsScriptMonitoring -Path "C:\Transcript.txt" `
-PassThru;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsScriptsMonitoring - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsScriptsMonitoring</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsScriptsMonitoring/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Enable-SnsScriptMonitoring -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Enable-SnsScriptMonitoring</command:name>
      <command:verb>Enable</command:verb>
      <command:noun>SnsScriptMonitoring</command:noun>
      <maml:description>
        <maml:para>Creates A Monitoring Entry In The Monitoring DataBase.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Creates A Monitoring Entry In The Monitoring DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Whenever A Script Fails It Either Have Its Process Stuck Without Being Able To Continue Further Or Its Process Completely Stop. In Both Cases The Script Cannot Notify About The Failure Nor Continue Further. From That Perspective Whenever We Have Automation Scripts Doing Business Critical Tasks We Need To Monitor Their Running Using Another Script Named Here Monitoring Script.</maml:para>
      <maml:para>Detecting A Failed Script Is Relatively Easy, Whenever We Have Failed Script Its Process Stops And No Longer Could Be Enumerated With The Machines Processes. A Monitoring Script Could Detect The Failure And Either Report Or Take Actions. However That's Not The Case With The Stuck Scripts. Their Processes Are Still Running And Just Doing Nothing. A Monitoring Script Could Be Easily Mistaken That A Stuck Script Is Running As Usual. Monitoring Of Stuck Scripts Can Be Achieved Via Using Of Transcript Files By The Monitored Scripts Which To Be Updated Regularly. The Monitored Script Could Check The LastWriteTime Of Those Transcript Files And Based On A Threshold Could Decide Whether Specific Monitored Script Is Stuck Or Continue To Be Updated.</maml:para>
      <maml:para>The Module Requires The Monitored Scripts To Write Output Regularly On Either Transcript Or Log File, Named Here Monitored File. From Within The Monitored Script Must Be Created A Monitoring Entry Kept In A Monitoring DataBase About The Monitored File Using Enable-SnsScriptMonitoring CmdLet. At The End Of The Monitored Script Running It Must Run Disable-SnsScriptMonitoring To Indicate It Is Completed Successfully And No Longer Needs To Be Monitored. Whenever Disabling From Monitoring Is Omitted The Module Still Can Identify Successfully Completed Scripts Using The Monitored Script Exit Code Supplied To Its Scheduled Task. In Order This To Work As Expected The Monitoring Entry Must Have The Correct Scheduled Task Path And Access Rights To Verify Whether Its State Is Ready And The Last Exit Code Is 0 (Exit Without Failures). Additionally The Monitored Script Must Supply That Information To Its Task. Whenever The Disabling From Monitoring Is Omitted Could Lead To Unexpected Results.</maml:para>
      <maml:para>We Use Get-SnsScriptMonitoringEntry CmdLet From Within The Monitoring Script To Monitor The Monitored Scripts. The CmdLet Is Capable To Automatically Restart The Failed Scripts, If Needed And The Prerequisites For That Are Met.</maml:para>
      <maml:para>Because The Monitored Script Could Be Stuck Or Failed We Need Additional Script Executed On A Schedule To Run Get-SnsScriptMonitoringEntry In Order To Monitor The Monitored Scripts Operation. The Monitoring Script Must Be Reliable And Not Resource Intensive. The Reliability And Performance Considerations Are The Main Reason This Module To Be Developed As Binary PowerShell Module.</maml:para>
      <maml:para>The "SnsPsScriptsMonitoring" PowerShell Module Contains All The CmdLets Required For Enable Monitoring, Disable Monitoring, And Being Monitored By A Dedicated Monitoring Script. All The Needed CmdLets Are In One Place And There Is No Monitoring And Monitoring Agent PowerShell Modules.</maml:para>
      <maml:para>The Module Requires The Monitored Scripts To Comply With The Following Requirements:</maml:para>
      <maml:para>- The Monitored Scripts Must Update Periodically Transcript Or Log Files. Whenever Those Files Are Not Modified For Specified Period Of Time Their Scripts Are Considered As Stuck. The Monitoring CmdLet Does Not Read The Content Of The Transcript Files. We Need The Monitoring Processes To Be Fast As Possible. Reading File Content Is Not Among The Operations Considered As Fast. The Account That Running The Get-SnsScriptMonitoringEntry CmdLet Requires NTFS Permissions Over The Monitored Files To Read Their LastWriteTime.</maml:para>
      <maml:para>- To Identify Failed Script Processes The Get-SnsScriptMonitoringEntry CmdLet Verifies Whether The Script Process Is Still Running. This Requires The Correct Process ID Of The Script Process To Be Present In The Monitoring Entry. The Process ID's Are Assigned By The Operating System Dynamically, Therefore They Cannot Be Specified At The Time When The Monitored Script Is Written And Provided To Enable-SnsScriptMonitoring CmdLet. However The PowerShell Can Dynamically Identify Its Own Process, And The Enable-SnsScriptMonitoring CmdLet Do So Dynamically. Therefore It Is Mandatory It To Be Run From The Monitored Script. In That Way In The Monitoring Entry Will Be Present The Correct Process ID Of The Monitored Script Process.</maml:para>
      <maml:para>Get-SnsScriptMonitoringEntry Can Identify The Properly Running Scripts. Depending On The Specified Parameters And The Information Available In The Monitoring Entry Could Action The Enumerated Failed And Or Stuck Scripts Via Stopping The Monitored Script Process And Restarting Of The Monitored Script Scheduled Task. To Ensure This Feature Is Available Make Sure As Much As Possible Information Is Provided When The Monitored Script Is Enabled For Monitoring.</maml:para>
      <maml:para>The CmdLets In This Module Can Work Only Locally Which Means That The Monitored Scripts And The Monitoring Script Must Run On The Same Machine.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The SnsPsScriptsMonitoring Uses An SQLite V3 Serverless DataBase To Keep Track Of The Monitored Scripts Information. When The PowerShell Module Is Loaded For The First Time It Automatically Creates The Monitoring DataBase At The Following Location:</maml:para>
      <maml:para>"%ProgramData%\SnsPsScriptsMonitoring\SnsScrMon.db"</maml:para>
      <maml:para>Because Creation Of Folders And Files Within That Folder Requires Elevated Access Rights The First Load Of The Module Must Be In Elevated PowerShell Process. The Consequent Loads Of The Module Does not Require Elevated Mode, Except Specific Feature Requires It, And The Feature Itself Is Required. For Example Restart Of The Failed Scripts Requires The Monitored Script To Be Run In Elevated Mode, But The User Might Need The Failures To Be Reported And Not Actioned. In That Case There Is No Point To Run The Monitoring Script In Elevated Mode.</maml:para>
      <maml:para>The Information Kept In The Monitoring DataBase Is: "Machine", "Directory", "Script", "MonitoredFile", "Task", "Pid", "Threshold", "Enabled" And "Disabled".</maml:para>
      <maml:para>"Machine" Is The Fully Qualified Domain Name (FQDN) Of The Machine Where The Monitored Script Is Running. This Is Automatically Enumerated By Enable-SnsScriptMonitoring CmdLet And No User Input Is Possible.</maml:para>
      <maml:para>"Directory" Is The Folder Where The Monitored File Reside. This Information Is Automatically Enumerated From The Specified Monitored File And No User Input Is Possible.</maml:para>
      <maml:para>"Script" Is The .PS1 FileName Of The Monitored Script. This Information Is Automatically Enumerated. In Order The Enumeration To Work Correctly, Enable-SnsScriptMonitoring CmdLet Must Be Run From The Monitored Script. The "Script" Name Is Used For RestartFailed Feature, And For The Automatic Disabling From Monitoring Of Failed Scripts When The Failed Script Is Restarted And Newer Monitoring Entry Is Created About New Monitoring File Of The Same Script. "Script" Is Not Mandatory However When The Value Is Missing Or Incorrect Those Features Will Not Work. In Case The CmdLet Is Included In Scripts PowerShell Modules, The CmdLet Will Wrongly Identify The Script Module File As Monitored Script, From That Perspective The CmdLet Must Be Called From The Monitored Script Main .PS1 File.</maml:para>
      <maml:para>"MonitoredFile" Is The Full Absolute UNC Path To The Specified Monitored File. This Must Be Explicitly Specified To Enable-SnsScriptMonitoring CmdLet. There Is No Automatic Enumeration.</maml:para>
      <maml:para>"Task" Is The Full Path Of The Monitored Script Windows Scheduled Task. This Information Is Not Mandatory However Without It No Automatic Restart Of The Failed Scripts Is Possible. The Module Can Auto Enumerate It With Limited Success. It Is Preferable That "Task" Is Explicitly Specified To Enable-SnsScriptMonitoring CmdLet.</maml:para>
      <maml:para>"Pid" Is The Process ID Of The Script's PowerShell Process. This Is Automatically Enumerated. In Order The Auto Enumeration To Identify The Correct Process, The Enable-SnsScriptMonitoring Must Be Run From The Monitored Script.</maml:para>
      <maml:para>"Threshold" Is The Time Interval In Minutes About Inactivity Of The Monitored Script Used As A Threshold To Identify Whether It Is Stuck. The Inactivity Is Measured Via Reading The LastWriteTime Of The Script Transcript Or Log File Specified As Monitored File. For The Correct Identifying Please Make Shure That The Monitored Script Updates Periodically The Specified Monitored File. The Threshold Shall Be Considered Carefully Depending On The Intervals That The Monitored File Is Updated. Wrong Threshold Could Cause False Positives And Working Script To Be Stopped And Restarted In The Middle Of A Heavy Task.</maml:para>
      <maml:para>"Enabled" Is The DateTime When The Monitoring Entry Is Created, Converted To FileTime.</maml:para>
      <maml:para>"Disabled" Is The DateTime When The Monitoring Entry Is Disabled And The Monitored Script Stopped To Be Monitored, Converted To FileTime. Disabling From Monitoring Might Happen In Three Scenarios:</maml:para>
      <maml:para></maml:para>
      <maml:para>-- When The Monitored Script Finish Successfully. This Requires At The End Of The Monitored Script Have To Be Called Disable-SnsScriptMonitoring CmdLet. The CmdLet Updates The Monitoring Entry Via Specifying The Current DateTime Converted To FileTime In "Disabled" Column Of The Monitoring Entry. From That Moment On The Monitored File Updates And The Script Process Running Are No Longer Evaluated.</maml:para>
      <maml:para>-- When The Monitored Script Fail And AutoDisable Feature Is Used And New Instance Of The Monitoring Script Is Started And Enabled For Monitoring. Then The Failed Old Instance Will Be Disabled From Monitoring. The Way The Failed Script Is Restarted Does Not Make Any Difference. This Feature Will Work As Long As The Monitored Entry Have The Correct Values In "Script", "Directory" And "Task" Properties. It Is Not Related With RestartFailed Feature.</maml:para>
      <maml:para>-- When The User Runs Manually Disable-SnsScriptMonitoring CmdLet. This Is The Only Option To Stop The Reports For Failed Scripts That Did Not Disabled Themselves From Monitoring And The Prerequisites For AutoDisable Feature Are Not Met. For Example When The Scheduled Task Is Not Provided And Its Enumeration Failed.</maml:para>
      <maml:para>During The Module Load The Outdated Monitoring Entries Are Deleted And The Monitoring Database Is Defragmented And Shrank To Release Its White Space To The Operating System. For Outdated Entries Are Considered The Ones Which Are Disabled More Than 14 Days Ago. Enabled Entries Are Never Threated As Outdated Regardless Of Their Age.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Enable-SnsScriptMonitoring</maml:name>
        <!-- Parameter: Path -->
        <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
          <maml:name>Path</maml:name>
          <maml:description>
            <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: PassThru -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>PassThru</maml:name>
          <maml:description>
            <maml:para>Specifies To The CmdLet To Revert The New MonitoringEntry Object.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: ScheduledTask -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>ScheduledTask</maml:name>
          <maml:description>
            <maml:para>Specifies The Path To The Monitored Script Windows Scheduled Task.</maml:para>
            <maml:para>If Omitted The CmdLet Will Try To Auto Enumerate It.</maml:para>
            <maml:para>If Auto Enumeration Fail And The Monitoring Entry Is Created Without Scheduled Task Path, The Auto Restart Feature Of Get-SnsScriptMonitoringEntry CmdLet Will Not Work.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Threshold -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Threshold</maml:name>
          <maml:description>
            <maml:para>Specifies The Script Inactivity Threshold In Minutes.</maml:para>
            <maml:para>Valid Range From 1 To 1440.</maml:para>
            <maml:para>The Threshold Have To Be Considered Carefully. In Case The Monitored Script Makes Heavy Tasks Which Could Take Time. While Those Tasks Are Running The Monitored Script Will Be Unable To Update Its Transcript Or Log File. If The Threshold Is Less Than The Time Required For The Heavy Task, The Monitoring CmdLet Will Wrongly Identify The Monitored Script As Failed And Depending On The Specified Parameters Might Restart The Script In The Middle Of The Heavy Task Causing Its Failure And Starting It From The Beginning.</maml:para>
          </maml:description>
          <command:parameterValue required="true">int</command:parameterValue>
          <dev:type>
            <maml:name>System.Int32</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>15</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: Path -->
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>Path</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>FilePath</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          <maml:para>This is an alias of the Path parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>TranscriptFile</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          <maml:para>This is an alias of the Path parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>LogFile</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          <maml:para>This is an alias of the Path parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: ScheduledTask -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>ScheduledTask</maml:name>
        <maml:description>
          <maml:para>Specifies The Path To The Monitored Script Windows Scheduled Task.</maml:para>
          <maml:para>If Omitted The CmdLet Will Try To Auto Enumerate It.</maml:para>
          <maml:para>If Auto Enumeration Fail And The Monitoring Entry Is Created Without Scheduled Task Path, The Auto Restart Feature Of Get-SnsScriptMonitoringEntry CmdLet Will Not Work.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Threshold -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Threshold</maml:name>
        <maml:description>
          <maml:para>Specifies The Script Inactivity Threshold In Minutes.</maml:para>
          <maml:para>Valid Range From 1 To 1440.</maml:para>
          <maml:para>The Threshold Have To Be Considered Carefully. In Case The Monitored Script Makes Heavy Tasks Which Could Take Time. While Those Tasks Are Running The Monitored Script Will Be Unable To Update Its Transcript Or Log File. If The Threshold Is Less Than The Time Required For The Heavy Task, The Monitoring CmdLet Will Wrongly Identify The Monitored Script As Failed And Depending On The Specified Parameters Might Restart The Script In The Middle Of The Heavy Task Causing Its Failure And Starting It From The Beginning.</maml:para>
        </maml:description>
        <command:parameterValue required="true">int</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>15</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: PassThru -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>PassThru</maml:name>
        <maml:description>
          <maml:para>Specifies To The CmdLet To Revert The New MonitoringEntry Object.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes />
    <command:returnValues>
      <!-- OutputType: MonitoringEntry -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsPsScriptsMonitoring.MonitoringEntry</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>Enable-SnsScriptMonitoring -Path "C:\Transcript.txt" -ScheduledTask "\MyScript" -Threshold 30;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsPsScriptsMonitoring.MonitoringEntry]$objEntry = Enable-SnsScriptMonitoring -Path "C:\Transcript.txt" `
-ScheduledTask "\MyScript" -Threshold 30 -PassThru;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsScriptsMonitoring - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsScriptsMonitoring</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsScriptsMonitoring/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Get-SnsScriptMonitoringEntry -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Get-SnsScriptMonitoringEntry</command:name>
      <command:verb>Get</command:verb>
      <command:noun>SnsScriptMonitoringEntry</command:noun>
      <maml:description>
        <maml:para>Enumerates Monitoring Entries, Evaluates About Failed Scripts And Restarts Them If Requested.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Enumerates Monitoring Entries, Evaluates About Failed Scripts And Restarts Them If Requested.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Whenever A Script Fails It Either Have Its Process Stuck Without Being Able To Continue Further Or Its Process Completely Stop. In Both Cases The Script Cannot Notify About The Failure Nor Continue Further. From That Perspective Whenever We Have Automation Scripts Doing Business Critical Tasks We Need To Monitor Their Running Using Another Script Named Here Monitoring Script.</maml:para>
      <maml:para>Detecting A Failed Script Is Relatively Easy, Whenever We Have Failed Script Its Process Stops And No Longer Could Be Enumerated With The Machines Processes. A Monitoring Script Could Detect The Failure And Either Report Or Take Actions. However That's Not The Case With The Stuck Scripts. Their Processes Are Still Running And Just Doing Nothing. A Monitoring Script Could Be Easily Mistaken That A Stuck Script Is Running As Usual. Monitoring Of Stuck Scripts Can Be Achieved Via Using Of Transcript Files By The Monitored Scripts Which To Be Updated Regularly. The Monitored Script Could Check The LastWriteTime Of Those Transcript Files And Based On A Threshold Could Decide Whether Specific Monitored Script Is Stuck Or Continue To Be Updated.</maml:para>
      <maml:para>The Module Requires The Monitored Scripts To Write Output Regularly On Either Transcript Or Log File, Named Here Monitored File. From Within The Monitored Script Must Be Created A Monitoring Entry Kept In A Monitoring DataBase About The Monitored File Using Enable-SnsScriptMonitoring CmdLet. At The End Of The Monitored Script Running It Must Run Disable-SnsScriptMonitoring To Indicate It Is Completed Successfully And No Longer Needs To Be Monitored. Whenever Disabling From Monitoring Is Omitted The Module Still Can Identify Successfully Completed Scripts Using The Monitored Script Exit Code Supplied To Its Scheduled Task. In Order This To Work As Expected The Monitoring Entry Must Have The Correct Scheduled Task Path And Access Rights To Verify Whether Its State Is Ready And The Last Exit Code Is 0 (Exit Without Failures). Additionally The Monitored Script Must Supply That Information To Its Task. Whenever The Disabling From Monitoring Is Omitted Could Lead To Unexpected Results.</maml:para>
      <maml:para>We Use Get-SnsScriptMonitoringEntry CmdLet From Within The Monitoring Script To Monitor The Monitored Scripts. The CmdLet Is Capable To Automatically Restart The Failed Scripts, If Needed And The Prerequisites For That Are Met.</maml:para>
      <maml:para>Because The Monitored Script Could Be Stuck Or Failed We Need Additional Script Executed On A Schedule To Run Get-SnsScriptMonitoringEntry In Order To Monitor The Monitored Scripts Operation. The Monitoring Script Must Be Reliable And Not Resource Intensive. The Reliability And Performance Considerations Are The Main Reason This Module To Be Developed As Binary PowerShell Module.</maml:para>
      <maml:para>The "SnsPsScriptsMonitoring" PowerShell Module Contains All The CmdLets Required For Enable Monitoring, Disable Monitoring, And Being Monitored By A Dedicated Monitoring Script. All The Needed CmdLets Are In One Place And There Is No Monitoring And Monitoring Agent PowerShell Modules.</maml:para>
      <maml:para>The Module Requires The Monitored Scripts To Comply With The Following Requirements:</maml:para>
      <maml:para>- The Monitored Scripts Must Update Periodically Transcript Or Log Files. Whenever Those Files Are Not Modified For Specified Period Of Time Their Scripts Are Considered As Stuck. The Monitoring CmdLet Does Not Read The Content Of The Transcript Files. We Need The Monitoring Processes To Be Fast As Possible. Reading File Content Is Not Among The Operations Considered As Fast. The Account That Running The Get-SnsScriptMonitoringEntry CmdLet Requires NTFS Permissions Over The Monitored Files To Read Their LastWriteTime.</maml:para>
      <maml:para>- To Identify Failed Script Processes The Get-SnsScriptMonitoringEntry CmdLet Verifies Whether The Script Process Is Still Running. This Requires The Correct Process ID Of The Script Process To Be Present In The Monitoring Entry. The Process ID's Are Assigned By The Operating System Dynamically, Therefore They Cannot Be Specified At The Time When The Monitored Script Is Written And Provided To Enable-SnsScriptMonitoring CmdLet. However The PowerShell Can Dynamically Identify Its Own Process, And The Enable-SnsScriptMonitoring CmdLet Do So Dynamically. Therefore It Is Mandatory It To Be Run From The Monitored Script. In That Way In The Monitoring Entry Will Be Present The Correct Process ID Of The Monitored Script Process.</maml:para>
      <maml:para>Get-SnsScriptMonitoringEntry Can Identify The Properly Running Scripts. Depending On The Specified Parameters And The Information Available In The Monitoring Entry Could Action The Enumerated Failed And Or Stuck Scripts Via Stopping The Monitored Script Process And Restarting Of The Monitored Script Scheduled Task. To Ensure This Feature Is Available Make Sure As Much As Possible Information Is Provided When The Monitored Script Is Enabled For Monitoring.</maml:para>
      <maml:para>The CmdLets In This Module Can Work Only Locally Which Means That The Monitored Scripts And The Monitoring Script Must Run On The Same Machine.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The SnsPsScriptsMonitoring Uses An SQLite V3 Serverless DataBase To Keep Track Of The Monitored Scripts Information. When The PowerShell Module Is Loaded For The First Time It Automatically Creates The Monitoring DataBase At The Following Location:</maml:para>
      <maml:para>"%ProgramData%\SnsPsScriptsMonitoring\SnsScrMon.db"</maml:para>
      <maml:para>Because Creation Of Folders And Files Within That Folder Requires Elevated Access Rights The First Load Of The Module Must Be In Elevated PowerShell Process. The Consequent Loads Of The Module Does not Require Elevated Mode, Except Specific Feature Requires It, And The Feature Itself Is Required. For Example Restart Of The Failed Scripts Requires The Monitored Script To Be Run In Elevated Mode, But The User Might Need The Failures To Be Reported And Not Actioned. In That Case There Is No Point To Run The Monitoring Script In Elevated Mode.</maml:para>
      <maml:para>The Information Kept In The Monitoring DataBase Is: "Machine", "Directory", "Script", "MonitoredFile", "Task", "Pid", "Threshold", "Enabled" And "Disabled".</maml:para>
      <maml:para>"Machine" Is The Fully Qualified Domain Name (FQDN) Of The Machine Where The Monitored Script Is Running. This Is Automatically Enumerated By Enable-SnsScriptMonitoring CmdLet And No User Input Is Possible.</maml:para>
      <maml:para>"Directory" Is The Folder Where The Monitored File Reside. This Information Is Automatically Enumerated From The Specified Monitored File And No User Input Is Possible.</maml:para>
      <maml:para>"Script" Is The .PS1 FileName Of The Monitored Script. This Information Is Automatically Enumerated. In Order The Enumeration To Work Correctly, Enable-SnsScriptMonitoring CmdLet Must Be Run From The Monitored Script. The "Script" Name Is Used For RestartFailed Feature, And For The Automatic Disabling From Monitoring Of Failed Scripts When The Failed Script Is Restarted And Newer Monitoring Entry Is Created About New Monitoring File Of The Same Script. "Script" Is Not Mandatory However When The Value Is Missing Or Incorrect Those Features Will Not Work. In Case The CmdLet Is Included In Scripts PowerShell Modules, The CmdLet Will Wrongly Identify The Script Module File As Monitored Script, From That Perspective The CmdLet Must Be Called From The Monitored Script Main .PS1 File.</maml:para>
      <maml:para>"MonitoredFile" Is The Full Absolute UNC Path To The Specified Monitored File. This Must Be Explicitly Specified To Enable-SnsScriptMonitoring CmdLet. There Is No Automatic Enumeration.</maml:para>
      <maml:para>"Task" Is The Full Path Of The Monitored Script Windows Scheduled Task. This Information Is Not Mandatory However Without It No Automatic Restart Of The Failed Scripts Is Possible. The Module Can Auto Enumerate It With Limited Success. It Is Preferable That "Task" Is Explicitly Specified To Enable-SnsScriptMonitoring CmdLet.</maml:para>
      <maml:para>"Pid" Is The Process ID Of The Script's PowerShell Process. This Is Automatically Enumerated. In Order The Auto Enumeration To Identify The Correct Process, The Enable-SnsScriptMonitoring Must Be Run From The Monitored Script.</maml:para>
      <maml:para>"Threshold" Is The Time Interval In Minutes About Inactivity Of The Monitored Script Used As A Threshold To Identify Whether It Is Stuck. The Inactivity Is Measured Via Reading The LastWriteTime Of The Script Transcript Or Log File Specified As Monitored File. For The Correct Identifying Please Make Shure That The Monitored Script Updates Periodically The Specified Monitored File. The Threshold Shall Be Considered Carefully Depending On The Intervals That The Monitored File Is Updated. Wrong Threshold Could Cause False Positives And Working Script To Be Stopped And Restarted In The Middle Of A Heavy Task.</maml:para>
      <maml:para>"Enabled" Is The DateTime When The Monitoring Entry Is Created, Converted To FileTime.</maml:para>
      <maml:para>"Disabled" Is The DateTime When The Monitoring Entry Is Disabled And The Monitored Script Stopped To Be Monitored, Converted To FileTime. Disabling From Monitoring Might Happen In Three Scenarios:</maml:para>
      <maml:para></maml:para>
      <maml:para>-- When The Monitored Script Finish Successfully. This Requires At The End Of The Monitored Script Have To Be Called Disable-SnsScriptMonitoring CmdLet. The CmdLet Updates The Monitoring Entry Via Specifying The Current DateTime Converted To FileTime In "Disabled" Column Of The Monitoring Entry. From That Moment On The Monitored File Updates And The Script Process Running Are No Longer Evaluated.</maml:para>
      <maml:para>-- When The Monitored Script Fail And AutoDisable Feature Is Used And New Instance Of The Monitoring Script Is Started And Enabled For Monitoring. Then The Failed Old Instance Will Be Disabled From Monitoring. The Way The Failed Script Is Restarted Does Not Make Any Difference. This Feature Will Work As Long As The Monitored Entry Have The Correct Values In "Script", "Directory" And "Task" Properties. It Is Not Related With RestartFailed Feature.</maml:para>
      <maml:para>-- When The User Runs Manually Disable-SnsScriptMonitoring CmdLet. This Is The Only Option To Stop The Reports For Failed Scripts That Did Not Disabled Themselves From Monitoring And The Prerequisites For AutoDisable Feature Are Not Met. For Example When The Scheduled Task Is Not Provided And Its Enumeration Failed.</maml:para>
      <maml:para>During The Module Load The Outdated Monitoring Entries Are Deleted And The Monitoring Database Is Defragmented And Shrank To Release Its White Space To The Operating System. For Outdated Entries Are Considered The Ones Which Are Disabled More Than 14 Days Ago. Enabled Entries Are Never Threated As Outdated Regardless Of Their Age.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: InputObject -->
      <command:syntaxItem>
        <maml:name>Get-SnsScriptMonitoringEntry</maml:name>
        <!-- Parameter: Path -->
        <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
          <maml:name>Path</maml:name>
          <maml:description>
            <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
            <maml:para>The Parameter Allows Wildcards Both In PowerShell And SQL Syntax.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
      <!-- Parameter set: All -->
      <command:syntaxItem>
        <maml:name>Get-SnsScriptMonitoringEntry</maml:name>
        <!-- Parameter: All -->
        <command:parameter required="true" globbing="false" pipelineInput="false" position="named">
          <maml:name>All</maml:name>
          <maml:description>
            <maml:para>Specifies To The CmdLet To Revert All Monitoring Entries Including The Disabled Ones.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
      <!-- Parameter set: Enabled -->
      <command:syntaxItem>
        <maml:name>Get-SnsScriptMonitoringEntry</maml:name>
        <!-- Parameter: Enabled -->
        <command:parameter required="true" globbing="false" pipelineInput="false" position="named">
          <maml:name>Enabled</maml:name>
          <maml:description>
            <maml:para>Specifies To The CmdLet To Revert Only The Enabled Entries Without To Take Any Mitigation Actions.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: RestartFailed -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>RestartFailed</maml:name>
          <maml:description>
            <maml:para>Specifies To The CmdLet To Restart The Failed Scripts.</maml:para>
            <maml:para>This Happens In Two Steps:</maml:para>
            <maml:para>-- Stopping The PowerShell Process Of A Stuck Script. The Script Must Not Updated Its Own Transcript File For Longer Than The Specified Threshold. This Step Requires The Correct Process ID To Be Available In The Monitoring Entry. Once The Process Of Stuck Script Is Stopped Effectively It Become Failed Script. This Requires The Account That Calling The CmdLet To Have Local Administrative Access Rights And To Be Run In Elevated PowerShell Session.</maml:para>
            <maml:para>-- Restarting Script's Scheduled Task. It Requires The Correct Scheduled Task Path To Be Available In The Monitoring Entry. In Order This To Work Properly The Scheduled Task Have To Be Configured To Allow Run On Demand And The Account That Runs The CmdLet To Have Local Administrative Access Rights On The Machine And The CmdLet To Be Run In Elevated PowerShell Session.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
      <!-- Parameter set: Failed -->
      <command:syntaxItem>
        <maml:name>Get-SnsScriptMonitoringEntry</maml:name>
        <!-- Parameter: Failed -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Failed</maml:name>
          <maml:description>
            <maml:para>Specifies To The CmdLet To Verify The State Of The Scripts Associated With The Monitoring Entries And Revert Only The Ones Which Are Enabled For Monitoring And Failed Or Stuck.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: RestartFailed -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>RestartFailed</maml:name>
          <maml:description>
            <maml:para>Specifies To The CmdLet To Restart The Failed Scripts.</maml:para>
            <maml:para>This Happens In Two Steps:</maml:para>
            <maml:para>-- Stopping The PowerShell Process Of A Stuck Script. The Script Must Not Updated Its Own Transcript File For Longer Than The Specified Threshold. This Step Requires The Correct Process ID To Be Available In The Monitoring Entry. Once The Process Of Stuck Script Is Stopped Effectively It Become Failed Script. This Requires The Account That Calling The CmdLet To Have Local Administrative Access Rights And To Be Run In Elevated PowerShell Session.</maml:para>
            <maml:para>-- Restarting Script's Scheduled Task. It Requires The Correct Scheduled Task Path To Be Available In The Monitoring Entry. In Order This To Work Properly The Scheduled Task Have To Be Configured To Allow Run On Demand And The Account That Runs The CmdLet To Have Local Administrative Access Rights On The Machine And The CmdLet To Be Run In Elevated PowerShell Session.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: Path -->
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>Path</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          <maml:para>The Parameter Allows Wildcards Both In PowerShell And SQL Syntax.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>FilePath</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          <maml:para>The Parameter Allows Wildcards Both In PowerShell And SQL Syntax.</maml:para>
          <maml:para>This is an alias of the Path parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>TranscriptFile</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          <maml:para>The Parameter Allows Wildcards Both In PowerShell And SQL Syntax.</maml:para>
          <maml:para>This is an alias of the Path parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="FilePath,TranscriptFile,LogFile">
        <maml:name>LogFile</maml:name>
        <maml:description>
          <maml:para>Specifies The Full Absolute UNC File Path To The Monitored Script Transcript File.</maml:para>
          <maml:para>The Parameter Allows Wildcards Both In PowerShell And SQL Syntax.</maml:para>
          <maml:para>This is an alias of the Path parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: All -->
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named">
        <maml:name>All</maml:name>
        <maml:description>
          <maml:para>Specifies To The CmdLet To Revert All Monitoring Entries Including The Disabled Ones.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Enabled -->
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named">
        <maml:name>Enabled</maml:name>
        <maml:description>
          <maml:para>Specifies To The CmdLet To Revert Only The Enabled Entries Without To Take Any Mitigation Actions.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Failed -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Failed</maml:name>
        <maml:description>
          <maml:para>Specifies To The CmdLet To Verify The State Of The Scripts Associated With The Monitoring Entries And Revert Only The Ones Which Are Enabled For Monitoring And Failed Or Stuck.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: RestartFailed -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>RestartFailed</maml:name>
        <maml:description>
          <maml:para>Specifies To The CmdLet To Restart The Failed Scripts.</maml:para>
          <maml:para>This Happens In Two Steps:</maml:para>
          <maml:para>-- Stopping The PowerShell Process Of A Stuck Script. The Script Must Not Updated Its Own Transcript File For Longer Than The Specified Threshold. This Step Requires The Correct Process ID To Be Available In The Monitoring Entry. Once The Process Of Stuck Script Is Stopped Effectively It Become Failed Script. This Requires The Account That Calling The CmdLet To Have Local Administrative Access Rights And To Be Run In Elevated PowerShell Session.</maml:para>
          <maml:para>-- Restarting Script's Scheduled Task. It Requires The Correct Scheduled Task Path To Be Available In The Monitoring Entry. In Order This To Work Properly The Scheduled Task Have To Be Configured To Allow Run On Demand And The Account That Runs The CmdLet To Have Local Administrative Access Rights On The Machine And The CmdLet To Be Run In Elevated PowerShell Session.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes />
    <command:returnValues>
      <!-- OutputType: MonitoringEntry -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsPsScriptsMonitoring.MonitoringEntry</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>[SnsPsScriptsMonitoring.MonitoringEntry[]]$arrEntries = Get-SnsScriptMonitoringEntry -Path "C:\Transcript.txt";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsPsScriptsMonitoring.MonitoringEntry[]]$arrEntries = Get-SnsScriptMonitoringEntry -All;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 3 ----------</maml:title>
        <dev:code>[SnsPsScriptsMonitoring.MonitoringEntry[]]$arrEntries = Get-SnsScriptMonitoringEntry -Enabled;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 4 ----------</maml:title>
        <dev:code>[SnsPsScriptsMonitoring.MonitoringEntry[]]$arrEntries = Get-SnsScriptMonitoringEntry -Enabled -RestartFailed;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 5 ----------</maml:title>
        <dev:code>[SnsPsScriptsMonitoring.MonitoringEntry[]]$arrEntries = Get-SnsScriptMonitoringEntry -Failed;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 6 ----------</maml:title>
        <dev:code>[SnsPsScriptsMonitoring.MonitoringEntry[]]$arrEntries = Get-SnsScriptMonitoringEntry -Failed -RestartFailed;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsScriptsMonitoring - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsScriptsMonitoring</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsScriptsMonitoring/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
</helpItems>