How to execute a query daily in a specific time (no SSIS no JOBS) - scheduled-tasks

I'm doing a generic extractor of information in vb.net to exec any SQL Server query, save data to a txt, compress and send it via FTP (similar to a SSIS package). I have a schedule information too, for example: I want to exec all the queries I configure at 8am and 3pm everyday.
so, I want to know what API should I use to achieve that, using the schedule information I configure? I want to replicate what sql server does with JOBS. I hope you can give some suggestions, thanks in advance

you can attach exe with windows scheduler. It will run your exe on time.

class TaskHelper {
//using System;
//using System.Diagnostics;
//using System.IO;
//using System.Security.Principal;
public static void CreateSchTasks() {
string output;
// links to documentation
// https://learn.microsoft.com/en-us/windows/win32/taskschd/schtasks
// https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/schtasks
// and this one to convert to vb.net
// https://codeconverter.icsharpcode.net/
output = SchTaskCmd($"/create /tn _my3amSQL /tr \"c:\\MyApps\\sql_ABC.exe\" /sc daily /st 03:00");
Console.WriteLine($"{output}");
output = SchTaskCmd($"/create /tn _my5thDaySQL /tr \"c:\\MyApps\\sql_DE.exe\" /sc monthly /d 5");
Console.WriteLine($"{output}");
output = SchTaskCmd($"/create /tn _my5thHourSQL /tr \"c:\\MyApps\\sql_xy.exe\" /sc hourly /mo 5");
Console.WriteLine($"{output}");
}
private static string SchTaskCmd(string cmdLine) {
Process p = new Process();
p.StartInfo.FileName = $"{Environment.GetFolderPath(Environment.SpecialFolder.System)}\\schtasks.exe";
p.StartInfo.Arguments = cmdLine;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
p.Dispose();
return output.Trim();
}
}

Related

How to stop a windows 10 machine from sleeping/hibernating down when running a powershell process?

I have a powershell process that reads records from a remote server and copies them into a local database. When it runs, it might run for 8-12 hours.
How do I prevent the computer from shutting down (or going into sleep/hibernate mode) during this time? I know I can adjust the 'Power and sleep settings' to set the computer to never sleep, but that's not what I'm looking for - I do want it to go to sleep when the process isn't running.
I know that sleep/hibernate is suspended if a netflix or youtube video is running, I'd like the computer to do the same when a powershell process is running.
The powershell process runs in a command window on the desktop - I'm happy for the screen saver to activate, but what I don't want to happen is for me to wake the machine after 8 hours and discover that the process only ran for 10 minutes before the computer went to sleep!
With some extra effort, you can achieve the desired behavior with the standard powercfg.exe utility, by using a custom, always-on power scheme that is created on demand and temporarily activated for the duration of your script run:
Note:
Look for comment # YOUR CODE GOES HERE below.
For a .NET / Windows API-based alternative, see this answer.
# Define the properties of a custom power scheme, to be created on demand.
$schemeGuid = 'e03c2dc5-fac9-4f5d-9948-0a2fb9009d67' # randomly created with New-Guid
$schemeName = 'Always on'
$schemeDescr = 'Custom power scheme to keep the system awake indefinitely.'
# Helper function that ensures that the most recent powercfg.exe call succeeded.
function assert-ok { if ($LASTEXITCODE -ne 0) { throw } }
# Determine the currently active power scheme, so it can be restored at the end.
$prevGuid = (powercfg -getactivescheme) -replace '^.+([-0-9a-f]{36}).+$', '$1'
assert-ok
# Temporarily activate a custom always-on power scheme; create it on demand.
try {
# Try to change to the custom scheme.
powercfg -setactive $schemeGuid 2>$null
if ($LASTEXITCODE -ne 0) { # Changing failed -> create the scheme on demand.
# Clone the 'High performance' scheme.
$null = powercfg -duplicatescheme SCHEME_MIN $schemeGuid
assert-ok
# Change its name and description.
$null = powercfg -changename $schemeGuid $schemeName $schemeDescr
# Activate it
$null = powercfg -setactive $schemeGuid
assert-ok
# Change all settings to be always on.
# Note:
# * Remove 'monitor-timeout-ac', 'monitor-timeout-dc' if it's OK
# for the *display* to go to sleep.
# * If you make changes here, you'll have to run powercfg -delete $schemeGuid
# or delete the 'Always on' scheme via the GUI for changes to take effect.
# * On an AC-only machine (desktop, server) the *-ac settings aren't needed.
$settings = 'monitor-timeout-ac', 'monitor-timeout-dc', 'disk-timeout-ac', 'disk-timeout-dc', 'standby-timeout-ac', 'standby-timeout-dc', 'hibernate-timeout-ac', 'hibernate-timeout-dc'
foreach ($setting in $settings) {
powercfg -change $setting 0 # 0 == Never
assert-ok
}
}
# YOUR CODE GOES HERE.
# In this sample, wait for the user to press Enter before exiting.
# Before that, the 'Always on' power scheme should remain in
# effect, and the machine shouldn't go to sleep.
pause
} finally { # Executes even when the script is aborted with Ctrl-C.
# Reactivate the previously active power scheme.
powercfg -setactive $prevGuid
}
You could create a wrapper script from the above, to which you pass the path of the script to execute.
If you don't mind modifying the currently active scheme, you can use the approach shown in Kerr's answer, using per-setting powercfg -change <setting> <value-in-minutes> calls (/x / -x is an alias of /change / -change), using one of the following <setting> names in each call; passing 0 as <value-in-minutes> represents never:
monitor-timeout-ac
monitor-timeout-dc
disk-timeout-ac
disk-timeout-dc
standby-timeout-ac
standby-timeout-dc
hibernate-timeout-ac
hibernate-timeout-dc
Note, however, that such changes are persistent, so you may want to restore the original values later, which takes extra effort.
To offer a .NET / Windows API-based alternative to the powercfg.exe-based solution:
Note:
The solution uses Add-Type to compile C# code on demand, which incurs a performance penalty the first time the code is called in the current session.
It is important to call ::StayAwake($false) in the same session in order to clear the power requests made.
Look for comment # YOUR CODE GOES HERE below.
This solution was adapted from this C# answer by MarkusEgle.
Add-Type -ErrorAction Stop -Name PowerUtil -Namespace Windows -MemberDefinition #'
// Member variables.
static IntPtr _powerRequest;
static bool _mustResetDisplayRequestToo;
// P/Invoke function declarations.
[DllImport("kernel32.dll")]
static extern IntPtr PowerCreateRequest(ref POWER_REQUEST_CONTEXT Context);
[DllImport("kernel32.dll")]
static extern bool PowerSetRequest(IntPtr PowerRequestHandle, PowerRequestType RequestType);
[DllImport("kernel32.dll")]
static extern bool PowerClearRequest(IntPtr PowerRequestHandle, PowerRequestType RequestType);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
static extern int CloseHandle(IntPtr hObject);
// Availablity Request Enumerations and Constants
enum PowerRequestType
{
PowerRequestDisplayRequired = 0,
PowerRequestSystemRequired,
PowerRequestAwayModeRequired,
PowerRequestMaximum
}
const int POWER_REQUEST_CONTEXT_VERSION = 0;
const int POWER_REQUEST_CONTEXT_SIMPLE_STRING = 0x1;
// Availablity Request Structures
// Note: Windows defines the POWER_REQUEST_CONTEXT structure with an
// internal union of SimpleReasonString and Detailed information.
// To avoid runtime interop issues, this version of
// POWER_REQUEST_CONTEXT only supports SimpleReasonString.
// To use the detailed information,
// define the PowerCreateRequest function with the first
// parameter of type POWER_REQUEST_CONTEXT_DETAILED.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct POWER_REQUEST_CONTEXT
{
public UInt32 Version;
public UInt32 Flags;
[MarshalAs(UnmanagedType.LPWStr)]
public string SimpleReasonString;
}
/// <summary>
/// Prevents the system from going to sleep, by default including the display.
/// </summary>
/// <param name="enable">
/// True to turn on, False to turn off. Passing True must be paired with a later call passing False.
/// If you pass True repeatedly, subsequent invocations take no actions and ignore the parameters.
/// If you pass False, the remaining paramters are ignored.
// If you pass False without having passed True earlier, no action is performed.
//// </param>
/// <param name="includeDisplay">True to also keep the display awake; defaults to True.</param>
/// <param name="reasonString">
/// A string describing why the system is being kept awake; defaults to the current process' command line.
/// This will show in the output from `powercfg -requests` (requires elevation).
/// </param>
public static void StayAwake(bool enable, bool includeDisplay = true, string reasonString = null)
{
if (enable)
{
// Already enabled: quietly do nothing.
if (_powerRequest != IntPtr.Zero) { return; }
// Configure the reason string.
POWER_REQUEST_CONTEXT powerRequestContext;
powerRequestContext.Version = POWER_REQUEST_CONTEXT_VERSION;
powerRequestContext.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
powerRequestContext.SimpleReasonString = reasonString ?? System.Environment.CommandLine; // The reason for making the power request.
// Create the request (returns a handle).
_powerRequest = PowerCreateRequest(ref powerRequestContext);
// Set the request(s).
PowerSetRequest(_powerRequest, PowerRequestType.PowerRequestSystemRequired);
if (includeDisplay) { PowerSetRequest(_powerRequest, PowerRequestType.PowerRequestDisplayRequired); }
_mustResetDisplayRequestToo = includeDisplay;
}
else
{
// Not previously enabled: quietly do nothing.
if (_powerRequest == IntPtr.Zero) { return; }
// Clear the request
PowerClearRequest(_powerRequest, PowerRequestType.PowerRequestSystemRequired);
if (_mustResetDisplayRequestToo) { PowerClearRequest(_powerRequest, PowerRequestType.PowerRequestDisplayRequired); }
CloseHandle(_powerRequest);
_powerRequest = IntPtr.Zero;
}
}
// Overload that allows passing a reason string while defaulting to keeping the display awake too.
public static void StayAwake(bool enable, string reasonString)
{
StayAwake(enable, false, reasonString);
}
'#
try {
# Create power request(s) that keep the system awake.
# Pass $false as the 2nd argument to allow the display to go to sleep.
# The reason string is visible when you run `powercfg.exe -requests` to show current requests
# (requires elevation).
# Defaults: keep the display awake too, use the current process' command line as the reason string.
[Windows.PowerUtil]::StayAwake($true, $true, "Running long-running script $PSCommandPath.")
# YOUR CODE GOES HERE.
# In this sample, wait for the user to press Enter before exiting.
# Before that, the system should stay awake indefinitely.
pause
} finally { # This ensures that the previous scheme is restored even when the script is aborted with Ctrl-C.
# Clear the power requests.
[Windows.PowerUtil]::StayAwake($false)
}
Simple one-liner that I use:
Powercfg /x -standby-timeout-ac 0

Run a long Powershell command as parameter when executing a BATCH file [duplicate]

This question already has answers here:
Convert a small PS script into a long line in a .BATch file
(3 answers)
Closed 4 years ago.
I want to run the following Powershell command by executing a .bat file:
Add-Type -TypeDefinition #'
using System.Runtime.InteropServices;
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume
{
// f(), g(), ... are unused COM method slots. Define these if you care
int f(); int g(); int h(); int i();
int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext);
int j();
int GetMasterVolumeLevelScalar(out float pfLevel);
int k(); int l(); int m(); int n();
int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext);
int GetMute(out bool pbMute);
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDevice
{
int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev);
}
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDeviceEnumerator
{
int f(); // Unused
int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint);
}
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { }
public class Audio
{
static IAudioEndpointVolume Vol()
{
var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;
IMMDevice dev = null;
Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(/*eRender*/ 0, /*eMultimedia*/ 1, out dev));
IAudioEndpointVolume epv = null;
var epvid = typeof(IAudioEndpointVolume).GUID;
Marshal.ThrowExceptionForHR(dev.Activate(ref epvid, /*CLSCTX_ALL*/ 23, 0, out epv));
return epv;
}
public static float Volume
{
get { float v = -1; Marshal.ThrowExceptionForHR(Vol().GetMasterVolumeLevelScalar(out v)); return v; }
set { Marshal.ThrowExceptionForHR(Vol().SetMasterVolumeLevelScalar(value, System.Guid.Empty)); }
}
public static bool Mute
{
get { bool mute; Marshal.ThrowExceptionForHR(Vol().GetMute(out mute)); return mute; }
set { Marshal.ThrowExceptionForHR(Vol().SetMute(value, System.Guid.Empty)); }
}
}
'#
[audio]::Volume = 1
The problem with cmd command prompt is that it interprets a new line of code as execute this command.
However, when I enter everything into a PowerShell command line, it does not do so.
Is there any possibility to run this whole PowerShell script by executing a batch script?
I have already tried powershell -command "and the whole script", but that did not work either... cmd keeps thinking a new line means to execute it.
Try this if you want to execute your PS1 File:
powershell.exe -executionpolicy bypass -file "YOUR_FILE_NAME.ps1"
If you want to do everythin in one batch File do this:
powershell.exe
"Your Command"
You just need to put your command into the next line.
First of all, if you have a long PowerShell command, the maximum limit of characters per cmd command line can be easily reached (I believe it is ~8191 characters?).
Furthermore, it is quite uncommon to execute such big PowerShell commands directly in the cmd command line. Usually you should put it inside a file ending with .ps1, and then you execute it using the following command:
powershell.exe -executionpolicy bypass -file script.ps1
In case you really need to run the PowerShell command as you mentioned, you must first modify it a little bit. Take as example the following PS script:
function Say-Hello
{
[CmdletBinding()]
Param
(
[string] $name
)
Process
{
# Let's say hello!
$str = "Hello " + $name
Write-Output $str
}
}
Say-Hello "Jason"
The trick is to replace all \r\n line endings with \n, using a text editor (like Notepad++ for instance):
HOWEVER, you must first add some ; at the end of many of your PowerShell commands, because that is the only way you can tell PowerShell that a new PowerShell command is being issued. Otherwise, PowerShell may take 2 lines of your code and execute them as a single one, since they look all concatenated after you removed the newlines.
Then remove all line comments from your code, and escape all double quotes (or alternatively, just replace them with single quotes):
function Say-Hello
{
[CmdletBinding()]
Param
(
[string] $name
)
Process
{
$str = 'Hello ' + $name;
Write-Output $str
}
}
Say-Hello 'Jason'
Now you are ready to copy it from your text editor tool (Notepad++ in my case) and paste it to your command line like this:
powershell.exe -executionpolicy bypass -command "function Say-Hello { [CmdletBinding()] Param ([string] $name) Process { $str = 'Hello ' + $name; Write-Output $str }} Say-Hello 'Jason'"
And the expected output for that is:
Hello Jason

Set Execution Policy Powershell in Azure web application

I need to execute some powershell code from a web api which I have deployed in an Azure App Service. I couldn't achieve to se 'Set-ExecutionPolicy' because I need to set it to unrestricted but I get an error
File D:\home\powershell\teams_v2.psm1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at http://go.microsoft.com/fwlink/?LinkID=135170
.
I have the following code
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();
var script = String.Format(#"Import-Module 'D:\home\powershell\teams_v2.psm1'
connect-teamsservice -user admin#contoso.onmicrosoft.com -tenant contoso.onmicrosoft.com
new-Team -displayname '{0}' -description '{1}' -smtpaddress '{2}' -alias '{3}' -type 'private'",
group.Name, group.Description, String.Format("{0}#contoso.onmicrosoft.com", group.MailNickName), "team");
RunspaceInvoke scriptInvoker = new RunspaceInvoke();
// set powershell execution policy to unrestricted
//scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(script);
// add an extra command to transform the script
// output objects into nicely formatted strings
// remove this line to get the actual objects
// that the script returns. For example, the script
// "Get-Process" returns a collection
// of System.Diagnostics.Process instances.
pipeline.Commands.Add("Out-String");
// execute the script
Collection <PSObject> results = pipeline.Invoke();
// close the runspace
runspace.Close();
// convert the script result into a single string
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
}
How can I achieve this to correctly load the ps module and use its functions.

Is there any way to clone Powershell Runspace object

I want to know if it is possible to create a new Powershell Runspace object from an old one.
I'm am going to do some powershell operations concurrently. I create powershell runspace every time and run certain commands. Let's say the first 5 commands are same for all operations. If I could run those commands only once for all operations and send a copy of the runspace to the multi threading method, it would be more efficient.
Means, I run some commands through a pipeline first.
Runspace runspace = RunspaceFactory.CreateRunspace()
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript("$var = 5"); //those 5 initial commands
pipeline.Invoke();
Now, I want to run certain commands concurrently.
Parallel.For(0, 5, new ParallelOptions { }, i => concurrentOperations(runspace, i));
The concurrentOperations method has been defined as this
private static void concurrentOperations(Runspace runspace, int i)
{
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript("$newVar = $var + " + i + "; $newVar"); //newer commands which differs for each operation
runspace.Open();
System.Collections.ObjectModel.Collection<PSObject> result = pipeline.Invoke();
foreach (PSObject obj in result)
{
Console.WriteLine("obj" + i + " : " + obj);
}
}
And now I encounter an exception that, "Pipelines cannot be run concurrently".
So, If I could make a copy of the runspace, the pipelines will be created for different runspaces only. But runspace doesnot have Clone() method in it.
Is there any way that I could achive this?

Parse script output from shell wanted in JScript

I want to execute a command and parse the output from the shell. I am using JScript inside TestComplete. I already found out that I can run commands using WScript.shell. But I do not know how to parse the output in my JScript. Any hints?
var shell = new ActiveXObject("WScript.shell");
if (shell)
{
shell.run("myCommandIWantToParseOutputfrom.sh");
}
Take a look at the Exec method instead of Run.
var wsh = new ActiveXObject("WScript.Shell");
var cmd = wsh.Exec("cmd /c dir C:\ /on");
while (cmd.Status === 0) {
WScript.Sleep(100);
}
var output = cmd.StdOut.ReadAll();
WScript.Echo(output);