Install Offline standalone CA for Domain

  1. Install standalone CA
  2. Change validity period to longer, so it can issue a longer period certificates.
    certutil -getreg ca\ValidityPeriod
    certutil -getreg ca\ValidityPeriodUnits
    certutil -setreg ca\ValidityPeriod "Years"
    certutil -setreg ca\ValidityPeriodUnits "20"
  3. Make standalone CA to support AD.  Don’t joint the standalone CA to domain.
    certutil -setreg ca\DSConfigDN "CN=Configuration,DC=yourdomain,DC=com"
    certutil -setreg ca\DSDomainDN "DC=yourdomain,DC=com"
  4. Change Extensions, CDP and AIA.  CRT and CRL are published to new locations instead of default, so they can be accessed by clients.
    1. Right click on the RootCA server name -> Properties -> Extensions tab -> extension type: CRL Distribution Point (CDP):.
    2. Select the line begins with “LDAP”, and click ‘Include in the CDP extension of issued certificates’.
    3. Select the line begins with “HTTP”, and click remove.  Do the same for the line begins with “file”.
    4. Click Add button, put: http://caservername.yourdomain.com/CertEnroll/<CaName><CRLNameSuffix><DeltaCRLAllowed&gt;.crl.  Check “Include in CRLs.” and “Include in the CDP extension of issued certificates”.  You can put in different location.
    5. Select the line begins with “C:\Windows”, and check “Publish CRLs to this location” and “Publish Delta CRLs to this location”.
    6. Change Extension type to Authority Information Access (AIA)
    7. Select the line begins with “LDAP”, and check “Include in the AIA extension of issued certificates”.
    8. Select the line begins with “HTTP”, and click remove.  Do the same for the line begins with “file”.
    9. Click Add button, put: http://caservername.yourdomain.com/CertEnroll/<ServerDNSName>_<CaName><CertificateName&gt;.crt.  Check “Include in the AIA extension of issued certificates”
    10. Click OK and allow the CA server to restart its service.  If you did this before certutil -setreg, then you need restart CA service after certutil -setreg.
  5. Right click on “Revoked certificates”-> Properties:
    1. CRL publication interval: 6 months
    2. Make sure “Publish Delta CRLs” is not checked
    3. Click OK
  6. Right click on “Revoked certificates” -> Publish.  or run this command
    certutil -crl
  7. Publish CRL & CRT to http location.  Copy the CRL & CRT file from %systemroot%\system32\CertSrv\CertEnroll of standalone CA to %systemroot%\system32\CertSrv\CertEnroll of SubCA, or the new location added in last steps if it is different.  If subca is not installed, just copy them to temperately location.
  8. Publish CRL & CRT to domain.  Run these commands
    certutil -dspublish -f <CAserverName>_<RootcaName>.crt RootCA
    certutil -dspublish -f <RootcaName>.crl
  9. Don’t issue SubCA certificate if these steps are not done.
  10. Install SubCA
  11. Test CRL & AIA on client certificates, export any client certificate to a .CER file. Run the following command against the .CER file.
    certutil -url file.cer or certutil -url file.crl
Posted in Uncategorized | Leave a comment

Write a GUI in Powershell – Part 7

7. Finish every else in Powershell. This script will run the timer. Once the time is reached, it will run the command.

# (C) Chao Liu
#===========================================================================
# Add CSharp Class to PowerShell
#===========================================================================

$path=$PSScriptRoot
$code=Get-Content -Raw -Path (Join-Path $path "PowerManagerNS.cs")
Add-Type -TypeDefinition $code

$csharp1=Get-Content (Join-Path $path "DynamicViewModel.cs") -Raw
#$csharp1=Get-Content "d:\Programming\XAML For PS\XAML For PS\DynamicDictViewModel.cs" -Raw
Add-Type -TypeDefinition $csharp1

#Add-Type -AssemblyName PresentationFramework
$csharp2=Get-Content (Join-Path $path "ConverterWrap.cs") -Raw
Add-Type -TypeDefinition $csharp2 -ReferencedAssemblies @("PresentationFramework";"WindowsBase")

$csharp3=Get-Content (Join-Path $path "MultiValueConverterWrap.cs") -Raw
Add-Type -TypeDefinition $csharp3 -ReferencedAssemblies @("PresentationFramework";"WindowsBase")

#===========================================================================
# Store Form Objects In PowerShell
#===========================================================================
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$xaml = Get-Content -Raw -Path (Join-Path $path "autoshutdown.xaml")

#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
catch{Write-Host "Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta, invalid XAML code was encountered."; exit}

$manager = New-Object System.Xml.XmlNamespaceManager $xaml.NameTable;
$manager.AddNamespace("xaml", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
$manager.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml");
$xaml.SelectNodes("//*[@x:Name]", $manager ) | %{Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}
#$xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}

#===========================================================================
# Create Data Module
#===========================================================================
$now=Get-Date
$viewModel = New-Object DynamicViewModel @{
Interval=1;
TotalTime=New-TimeSpan $now $now.AddHours(1);
EndTime=$now.AddHours(1);
StartTime=$now;
IdleTime=5;
DefaultIdleTime=0;
Running=New-Object TimeSpan;
Stopped=$true;
TypeKey="CountDown";
ExtraMsg="";
Display={("`n{0,-20}{1}" -f "Name","Value"); ("{0,-20}{1}" -f "----------","---------"); $viewModel.Keys |
%{"{0,-20}{1}" -f $_,(&{if(([String]$viewModel[$_]).length -ge 60) {([String]$viewModel[$_]).Substring(0,57)+"..."} else {$viewModel[$_]}})} | Sort }
}

$window.DataContext = $viewModel

#===========================================================================
$c= New-Object ConverterWrap
$c.ConvertPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
if ($parameter -eq $value){
$true
}
else {
$false
}
}
$c.ConvertBackPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
if ($value) {
$parameter
} else {
[System.Windows.Data.Binding]::DoNothing
}
}

$b=New-Object System.Windows.Data.Binding "TypeKey"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="CountDown"
$b.UpdateSourceTrigger="PropertyChanged"
$rbCountDown.SetBinding([System.Windows.Controls.RadioButton]::IsCheckedProperty, $b) | out-null

$b=New-Object System.Windows.Data.Binding "TypeKey"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="EndTime"
$b.UpdateSourceTrigger="PropertyChanged"
$rbEndTime.SetBinding([System.Windows.Controls.RadioButton]::IsCheckedProperty, $b) | out-null

$b=New-Object System.Windows.Data.Binding "TypeKey"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="IdleTime"
$b.UpdateSourceTrigger="PropertyChanged"
$rbIdleTime.SetBinding([System.Windows.Controls.RadioButton]::IsCheckedProperty, $b) | out-null

$b=New-Object System.Windows.Data.Binding "TypeKey"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="KeepAwake"
$b.UpdateSourceTrigger="PropertyChanged"
$rbKeepAwake.SetBinding([System.Windows.Controls.RadioButton]::IsCheckedProperty, $b) | out-null

#===========================================================================
for ($i=0; $i -lt 24; $i++) {
$cbHours.Items.Add($i) | Out-Null
}
for ($i=0; $i -lt 60; $i++) {
$cbMinutes.Items.Add($i) | Out-Null
}
for ($i=0; $i -lt 60; $i++) {
$cbSeconds.Items.Add($i) | Out-Null
}

$c= New-Object ConverterWrap
#$c.debugLevel=1
$c.ConvertPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
#Write-Host "c.ConvertBackPS: " $value
if ($parameter -eq "Hours"){
$value.Hours
}
elseif ($parameter -eq "Minutes"){
$value.Minutes
}
elseif ($parameter -eq "Seconds"){
$value.Seconds
}
else {
[System.Windows.DependencyProperty]::UnsetValue
}
}
$c.ConvertBackPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
try{
if ($parameter -eq "Hours"){
New-TimeSpan -Hours $value -Minutes $viewModel.TotalTime.Minutes -Seconds $viewModel.TotalTime.Seconds
}
elseif ($parameter -eq "Minutes"){
New-TimeSpan -Hours $viewModel.TotalTime.Hours -Minutes $value -Seconds $viewModel.TotalTime.Seconds
}
elseif ($parameter -eq "Seconds"){
New-TimeSpan -Hours $viewModel.TotalTime.Hours -Minutes $viewModel.TotalTime.Minutes -Seconds $value
}
else {
[System.Windows.DependencyProperty]::UnsetValue
}

}
catch {
[System.Windows.DependencyProperty]::UnsetValue
#[System.Windows.Data.Binding]::DoNothing
}
}

$b=New-Object System.Windows.Data.Binding "TotalTime"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="Hours"
$b.UpdateSourceTrigger="LostFocus"
$cbHours.SetBinding([System.Windows.Controls.ComboBox]::TextProperty, $b) | out-null

$b=New-Object System.Windows.Data.Binding "TotalTime"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="Minutes"
$b.UpdateSourceTrigger="LostFocus"
$cbMinutes.SetBinding([System.Windows.Controls.ComboBox]::TextProperty, $b) | out-null

$b=New-Object System.Windows.Data.Binding "TotalTime"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="Seconds"
$b.UpdateSourceTrigger="LostFocus"
$cbSeconds.SetBinding([System.Windows.Controls.ComboBox]::TextProperty, $b) | out-null

#===========================================================================
$c1= New-Object ConverterWrap
#$c1.debugLevel=1
$c1.ConvertPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
"{0:MM/dd/yyyy hh:mm:ss tt}" -f $value
#([Datetime]$value).ToString("MM/dd/yyyy hh:mm:ss tt")
#$value
}
$c1.ConvertBackPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
Write-Host "c1.ConvertBackPS: " $value
try{
[Datetime]$value
}
catch {
[System.Windows.DependencyProperty]::UnsetValue
#[System.Windows.Data.Binding]::DoNothing
}
}

$b=New-Object System.Windows.Data.Binding "EndTime"
$b.Mode="TwoWay"
$b.Converter=$c1
#$b.StringFormat="{0:MM/dd/yyyy hh:mm:ss tt}"
#$b.UpdateSourceTrigger="PropertyChanged"
$tbEndTime.SetBinding([System.Windows.Controls.TextBox]::TextProperty, $b) | out-null

#===========================================================================
$tick={
#Write-Host $args[0]
#Write-Host $args[1]

$now=Get-Date
switch ($viewModel.TypeKey) {
"CountDown" {
$viewModel.Running -= $timer.Interval
}
"EndTime" {
$viewModel.Running = $viewModel.EndTime - $now
}
"IdleTime" {
$viewModel.spinfo = [PowerManagerNS.PowerManager]::GetPowerInformation()
#$pbStatus.Value = [int]$viewModel.IdleTime*60 - $viewModel.DefaultIdleTime + $viewModel.spinfo.TimeRemaining
$viewModel.Running -= $timer.Interval
#            Write-Host ([int]$viewModel.IdleTime*60 - $viewModel.DefaultIdleTime + $viewModel.spinfo.TimeRemaining -
#                $viewModel.Running.Totalseconds)
if ((([int]$viewModel.IdleTime*60 - $viewModel.DefaultIdleTime + $viewModel.spinfo.TimeRemaining -
$viewModel.Running.Totalseconds) -gt 30) -and
($viewModel.spinfo.TimeRemaining -eq $viewModel.DefaultIdleTime)){
$viewModel.Running = [timespan]::FromMinutes([int]$viewModel.IdleTime)
}
}
"KeepAwake" {
$viewModel.Running = $now - $viewModel.StartTime
$viewModel.spinfo = [PowerManagerNS.PowerManager]::GetPowerInformation()
#$tbStatus.Text = "Keep Awake. Idle Time: $($viewModel.spinfo.TimeRemaining)"
[PowerManagerNS.PowerManager]::SetThreadExecutionState([PowerManagerNS.PowerManager]::ES_SYSTEM_REQUIRED)
}
}
if ($viewModel.Running.TotalSeconds -gt 0 -and  $viewModel.Running.TotalSeconds -lt $viewModel.Interval*4){
[console]::beep(500,300)
}
if (($viewModel.Running.TotalSeconds -le 0) -and ($viewModel.TypeKey -ne "KeepAwake")){
$timer.Stop();
$viewModel.stopped=$true
$btStart.Content="Start"
[console]::beep(900,900)
TimeReached
}
#UpdateStatus -now $now
}

#===========================================================================
$mc=New-Object MultiValueConverterWrap
$mc.ConvertPS={
param([Object[]]$value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
$return = $value[0] + " - " + (&{ if($value[3]){"Stopped"} else {"Running"}}) + "`n"
switch ($value[0]) {
"CountDown" {
$end=$now + $viewModel.Running
$text = "Now: $now `nTotal " + ("{0:hh\:mm\:ss}" -f $viewModel.Running) + " to $end"
}

"EndTime" {
$s=[Int]$viewModel.Running.TotalSeconds
$text= "Now: $now `nTotal " + ("{0:hh\:mm\:ss}" -f $viewModel.Running) + " to $($viewModel.EndTime)"
}

"IdleTime" {
$ts =  [timespan]::fromseconds($viewModel.spinfo.TimeRemaining)
$end=$now + $ts
$text = "Idle: "+ ("{0:hh\:mm\:ss}" -f $ts) +"`n" +
"Remain: " + "{0:hh\:mm\:ss}" -f $viewModel.Running
}

"KeepAwake" {
$ts =  [timespan]::fromseconds($viewModel.spinfo.TimeRemaining)
$text = "Idle: "+ ("{0:hh\:mm\:ss}" -f $ts) +"`n" +
"Pass: " + "{0:hh\:mm\:ss}" -f $viewModel.Running
}
}
if ($value[3]) {
$tbStatus.Background = [System.Windows.Media.Brushes]::Transparent

} else {
if (($viewModel.Running.TotalSeconds -lt 60) -and ($viewModel.TypeKey -ne "KeepAwake")){
$tbStatus.Background = [System.Windows.Media.Brushes]::Red
}
}
$return + $text + "`n" + $value[5]

}
$mc.ConvertBackPS={
param($value, $targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
$null
}
$mb = New-Object System.Windows.Data.MultiBinding;
$mb.Converter = $mc;
$mb.Mode = "OneWay"

$b1=New-Object System.Windows.Data.Binding "TypeKey"
$b2=New-Object System.Windows.Data.Binding "TotalTime"
$b3=New-Object System.Windows.Data.Binding "EndTime"
$b4=New-Object System.Windows.Data.Binding "Stopped"
$b5=New-Object System.Windows.Data.Binding "Running"
$b6=New-Object System.Windows.Data.Binding "ExtraMsg"
$mb.Bindings.Add($b1);
$mb.Bindings.Add($b2);
$mb.Bindings.Add($b3);
$mb.Bindings.Add($b4);
$mb.Bindings.Add($b5);
$mb.Bindings.Add($b6);
$tbStatus.SetBinding([System.Windows.Controls.TextBox]::TextProperty, $mb) | out-null

#===========================================================================

$cbHours.add_GotFocus({
#$rbCountDown.IsChecked = $true
$viewModel.TypeKey="CountDown"
})
$cbMinutes.add_GotFocus({
#$rbCountDown.IsChecked = $true
$viewModel.TypeKey="CountDown"
})
$cbSeconds.add_GotFocus({
#$rbCountDown.IsChecked = $true
$viewModel.TypeKey="CountDown"
})

$tbEndTime.add_GotFocus({
#$rbEndTime.IsChecked = $true
$viewModel.TypeKey="EndTime"
})

$cbIdleTime.add_GotFocus({
#$rbIdleTime.IsChecked = $true
$viewModel.TypeKey="IdleTime"
})

#Timer Event
$btStart.Add_Click({
#Create Timer object
$now = Get-Date
if (-not $timer) {
#System.Windows.Forms.Timer
$Global:timer = new-object  System.Windows.Threading.DispatcherTimer
$timer.Interval = [TimeSpan]::fromseconds($viewModel.Interval) #($cbInterval.Text)
$timer.Add_Tick($tick)
}

if ($viewModel.Stopped){

switch ($viewModel.TypeKey) {
"CountDown" {
$viewModel.Running = $viewModel.TotalTime
#$pbStatus.Value = $viewModel.Running.TotalSeconds
}

"EndTime" {
$viewModel.Running = $viewModel.EndTime - $now
#$pbStatus.Value = $viewModel.Running.TotalSeconds
}

"IdleTime" {
$viewModel.StartTime = $now
$viewModel.spinfo = [PowerManagerNS.PowerManager]::GetPowerInformation()
$viewModel.DefaultIdleTime = $viewModel.spinfo.TimeRemaining
$viewModel.Running = [timespan]::FromMinutes([int]$viewModel.IdleTime)
#$pbStatus.Value = [int]$viewModel.IdleTime*60 - $viewModel.DefaultIdleTime + $viewModel.spinfo.TimeRemaining
#$tbStatus.Text = "Idle: $ts Now: $now to $end"
}

"KeepAwake" {
$viewModel.StartTime = $now
$viewModel.spinfo = [PowerManagerNS.PowerManager]::GetPowerInformation()
#$tbStatus.Text = "Keep Awake. Idle Time: $($viewModel.spinfo.TimeRemaining)"
}
}
$timer.Interval = [TimeSpan]::fromseconds($viewModel.Interval)

$pbStatus.Minimum = 0
$pbStatus.Maximum = $viewModel.Running.TotalSeconds
$viewModel.Stopped = $false;
#        if ($viewModel.Running -lt [TimeSpan]::FromSeconds(60)){
#            $tbStatus.Background = [System.Windows.Media.Brushes]::Red
#        } else {
#            $tbStatus.Background = [System.Windows.Media.Brushes]::Transparent
#        }
}

if ($timer.IsEnabled){
$timer.Stop();
$btStart.Content="Start"
#$tbStatus.Text = "Paused`n" + $tbStatus.Text
} else {
#$timer.Interval = [TimeSpan]::fromseconds($cbInterval.Text)
$timer.Start()
$btStart.Content="Pause"
}

#UpdateStatus -now $now
})

$btReset.Add_Click({
if ($timer) { $timer.Stop()};
$btStart.Content="Start"
$viewModel.Stopped=$true
$viewModel.Running = New-Object Timespan
$pbStatus.Maximum=1

})

$btNow.add_Click({
$viewModel.EndTime = (Get-Date).AddHours(1)
})

#===========================================================================

function ExecText($command) {
try{
if ($command[0] -eq '"') { iex "& $command" }
else { iex $command }
$tbCmd.Background=[System.Windows.Media.Brushes]::Transparent
$viewModel.ExtraMsg=''
} catch {
Write-Host $_
$viewModel.ExtraMsg=$_
$tbCmd.Background=[System.Windows.Media.Brushes]::Red
}
}

function TimeReached(){
#$tbStatus.Text="Time Reached!"
#Shutdown.exe -t 30 -s
ExecText $tbCmd.Text
}

$btExec.Add_Click({
#Shutdown.exe -a
ExecText $tbCmd.Text
})

#===========================================================================
$Form.ShowDialog() | Out-Null

Posted in C#, Powershell, XAML | Leave a comment

Write a GUI in Powershell – Part 6

6a. This is the last C# class. This class will call function in Kernel.dll and PowrProf.dll to get power info.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PowerManagerNS
{

//public Guid GUID_SLEEP_SUBGROUP = new Guid("238C9FA8-0AAD-41ED-83F4-97BE242C8F20");
public static class PowerManager
{

public const uint WM_POWERBROADCAST         = 0x0218; // 536
public const uint PBT_APMQUERYSUSPEND       = 0x0000;
public const uint PBT_APMQUERYSTANDBY       = 0x0001;
public const uint PBT_APMQUERYSUSPENDFAILED = 0x0002;
public const uint PBT_APMQUERYSTANDBYFAILED = 0x0003;
public const uint PBT_APMSUSPEND            = 0x0004;
public const uint PBT_APMSTANDBY            = 0x0005;
public const uint PBT_APMRESUMECRITICAL     = 0x0006;
public const uint PBT_APMRESUMESUSPEND      = 0x0007;
public const uint PBT_APMRESUMESTANDBY      = 0x0008;
public const uint PBT_APMBATTERYLOW         = 0x0009;
public const uint PBT_APMPOWERSTATUSCHANGE  = 0x000A;
public const uint PBT_APMOEMEVENT           = 0x000B;
public const uint PBT_APMRESUMEAUTOMATIC    = 0x0012;
public const uint PBTF_APMRESUMEFROMFAILURE = 0x00000001;
public const uint ES_DISPLAY_REQUIRED       = 0x00000002; // zero the display''s idle timer
public const uint ES_SYSTEM_REQUIRED        = 0x00000001; // zero the system''s idle timer
public const uint ES_CONTINUOUS             = 0x80000000; // keep the display or system on (doesn''t work?)
public const uint BROADCAST_QUERY_DENY      = 0x424D5144;

public const int SystemPowerInformation = 12;
public const uint STATUS_SUCCESS = 0;

public static Guid GUID_SLEEP_SUBGROUP = new Guid("238C9FA8-0AAD-41ED-83F4-97BE242C8F20");

[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_POWER_INFORMATION
{
public uint MaxIdlenessAllowed;
public uint Idleness;
public uint TimeRemaining;
public Byte CoolingMode;
}

public static long size
{
get
{
return System.Runtime.InteropServices.Marshal.SizeOf(typeof(SYSTEM_POWER_INFORMATION));
}
}

[DllImport("PowrProf.dll", CharSet = CharSet.Auto,SetLastError = true)]
public static extern uint CallNtPowerInformation(int InformationLevel, IntPtr lpInputBuffer, long nInputBufferSize,
IntPtr lpOutputBuffer, long nOutputBufferSize);

[DllImport("PowrProf.dll", CharSet = CharSet.Auto,SetLastError = true)]
public static extern uint CallNtPowerInformation(int InformationLevel, IntPtr lpInputBuffer, long nInputBufferSize,
out SYSTEM_POWER_INFORMATION lpOutputBuffer, long nOutputBufferSize);

[DllImport("kernel32.dll", CharSet = CharSet.Auto,SetLastError = true)]
public static extern void SetThreadExecutionState(uint esFlags);

[DllImport("PowrProf.dll", CharSet = CharSet.Auto,SetLastError = true)]
public static extern Int32 PowerReadValueMax(
IntPtr RootPowerKey,
ref Guid SubGroupOfPowerSettingsGuid,
ref Guid PowerSettingGuid,
ref Int32 ValueMaximum
);

public static SYSTEM_POWER_INFORMATION GetPowerInformation1()
{
SYSTEM_POWER_INFORMATION spinfo = new SYSTEM_POWER_INFORMATION();
IntPtr pointer = Marshal.AllocHGlobal(Marshal.SizeOf(spinfo));
Marshal.StructureToPtr(spinfo, pointer, true);
CallNtPowerInformation(SystemPowerInformation, (IntPtr)0, 0, pointer, size);
spinfo = (SYSTEM_POWER_INFORMATION)Marshal.PtrToStructure(pointer, typeof(SYSTEM_POWER_INFORMATION));

return spinfo;
}

public static SYSTEM_POWER_INFORMATION GetPowerInformation()
{
SYSTEM_POWER_INFORMATION spinfo;
uint retval = CallNtPowerInformation(SystemPowerInformation, (IntPtr)0, 0, out spinfo, Marshal.SizeOf(typeof(SYSTEM_POWER_INFORMATION)));
if (retval == STATUS_SUCCESS)
return spinfo;
else
{
Console.WriteLine("Error: " + retval);
return new SYSTEM_POWER_INFORMATION();
}
}

public static Int32 GetPowerReadValueMax()
{
Int32 value=0;
Guid g = new Guid("238C9FA8-0AAD-41ED-83F4-97BE242C8F20");
Guid g2 = Guid.Empty;
Int32 retval = PowerReadValueMax((IntPtr)null, ref GUID_SLEEP_SUBGROUP, ref g2, ref value);
if (retval == STATUS_SUCCESS)
return value;
else
return retval;

}
}
}

6b. Add to Powershell

$code=Get-Content -Raw -Path (Join-Path $path "PowerManagerNS.cs")
Add-Type -TypeDefinition $code

Posted in C#, Powershell, XAML | Leave a comment

Write a GUI in Powershell – Part 5

5a. Create an other C# class

using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Data;
using System.Management.Automation;
public class MultiValueConverterWrap : IMultiValueConverter
{
public Func<object[], Type, object, CultureInfo, PSObject> ConvertPS;
public Func<object, Type[], object, CultureInfo, PSObject> ConvertBackPS;
public int debugLevel = 0;

public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
{
try
{
DebugPrint("ConverterWrap: Convert: ");
PSObject p = ConvertPS(value, targetType, parameter, culture);
if (p == null)
{
DebugPrint("ConverterWrap: ConvertBack: null");
return null;
}
else
{
//Object o = p.ImmediateBaseObject;
Object o = p.BaseObject;
//Type t = o.GetType;
return o;
}
}
catch (Exception e)
{
DebugPrint(e.Message);
return System.Windows.DependencyProperty.UnsetValue;
}
}

public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
DebugPrint("ConverterWrap: ConvertBack: ");
PSObject p = ConvertBackPS(value, targetType, parameter, culture);
DebugPrint("ConverterWrap: ConvertBack: " + p + "\t" + p.GetType());
//Object o = p.ImmediateBaseObject;
Object[] o = (Object[])p.BaseObject;
return o;
}
catch (Exception e)
{
DebugPrint(e.Message);
return null; //System.Windows.DependencyProperty.UnsetValue;
}
}

protected void DebugPrint(String s)
{
if (debugLevel == 1)
{
Console.WriteLine(s);
}
}
}

5b. add to Powershell
$csharp3=Get-Content (Join-Path $path "MultiValueConverterWrap.cs") -Raw
Add-Type -TypeDefinition $csharp3 -ReferencedAssemblies @("PresentationFramework";"WindowsBase")

Posted in C#, Powershell, XAML | Leave a comment

Write a GUI in Powershell – Part 4

4a. Create converter in C# for data binding for the same reason, Powershell doesn’t support C# interface.

using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Data;
using System.Management.Automation;

public class ConverterWrap : IValueConverter
{
public Func<object, Type, object, CultureInfo, PSObject> ConvertPS;
public Func<object, Type, object, CultureInfo, PSObject> ConvertBackPS;
public int debugLevel = 0;

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
DebugPrint("ConverterWrap: Convert: ");
PSObject p = ConvertPS(value, targetType, parameter, culture);
if (p == null)
{
DebugPrint("ConverterWrap: ConvertBack: null");
return null;
}
else
{
//Object o = p.ImmediateBaseObject;
Object o = p.BaseObject;
return o;
}
}
catch (Exception e)
{
DebugPrint(e.Message);
return System.Windows.DependencyProperty.UnsetValue;
}
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
DebugPrint("ConverterWrap: ConvertBack: ");
PSObject p = ConvertBackPS(value, targetType, parameter, culture);
if (p == null)
{
DebugPrint("ConverterWrap: ConvertBack: null");
return null;
}
else
{
DebugPrint("ConverterWrap: ConvertBack: " + p + "\t" + p.GetType());
//Object o = p.ImmediateBaseObject;
Object o = p.BaseObject;
//DebugPrint("ConverterWrap: ConvertBack: " + o + "\t" + o.GetType());
return o;
}
}
catch (Exception e)
{
DebugPrint(e.Message);
return System.Windows.DependencyProperty.UnsetValue;
}

}

protected void DebugPrint(String s)
{
if (debugLevel == 1)
{
Console.WriteLine(s);
}
}
}

4b. Add it to Powershell

$csharp2=Get-Content (Join-Path $path "ConverterWrap.cs") -Raw
Add-Type -TypeDefinition $csharp2 -ReferencedAssemblies @("PresentationFramework";"WindowsBase")

Posted in C#, Powershell, XAML | Leave a comment

Write a GUI in Powershell – Part 3

3a. Create data module in C#, This is useful when doing data binding. Don’t know if Powershell is able to create a custom object inherit a C# interface. But Powershell can use Add-Type to add a C# class. Then we just create a simple C# class, and add it to Powershell.

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Dynamic;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.ComponentModel;
using System.Management.Automation;

public class DynamicViewModel : DynamicObject, INotifyPropertyChanged
{
private Hashtable properties;
public event PropertyChangedEventHandler PropertyChanged;
public int debugLevel=0;

public DynamicViewModel()
{
this.properties = new Hashtable();
}

public DynamicViewModel(Hashtable data)
{
this.properties = data;
}

public int Count
{
get
{
return properties.Count;
}
}

public System.Collections.ICollection Keys
{
get
{
return properties.Keys;
}
}

public System.Collections.ICollection Values
{
get
{
return properties.Values;
}
}

// If you try to get a value of a property
// not defined in the class, this method is called.
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
DebugPrint("Get: " + binder.Name + " = " +  " | " + binder.Name.GetType());
result = properties.ContainsKey(binder.Name) ? properties[binder.Name] : null;
return true;
}

// If you try to set a value of a property that is
// not defined in the class, this method is called.
public override bool TrySetMember(SetMemberBinder binder, object value)
{
DebugPrint("TrySetMember: " + binder.Name + " = " + value + " | " + binder.Name.GetType() + " = " + value.GetType());
properties[binder.Name] = value;
RaisePropertyChanged(binder.Name);
return true;
}

// Get the property value by index.
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
DebugPrint("TryGetIndex: " + indexes[0] + " = " + " | " + indexes[0].GetType());
result = properties.ContainsKey(indexes[0].ToString()) ? properties[indexes[0].ToString()] : null;
return true;
}

// Set the property value by index.
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
try
{
DebugPrint("TrySetIndex: " + indexes[0] + " = " + value + " | " + indexes[0].GetType() + " = " + value.GetType());
//properties[indexes[0].ToString()] = value;
properties[(String)indexes[0]] = value;
RaisePropertyChanged((String)indexes[0]);
return true;
}
catch (Exception e)
{
DebugPrint("TrySetIndex Exception: " + e);
return false;
}

}

public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
DebugPrint("TryInvokeMember: ");
try
{
if (properties.ContainsKey(binder.Name))
{
DebugPrint("TryInvokeMember Key Found: " + binder.Name + " | " + properties[binder.Name].GetType());
result = ((ScriptBlock)properties[binder.Name]).InvokeReturnAsIs(args);
//result = ((Func<object[], object>)properties[binder.Name]).Invoke(args);
DebugPrint("TryInvokeMember Key Found - result: " + result);
}
else
{
DebugPrint("TryInvokeMember Key Not Found: " + binder.Name);
result = null;
return false;
}
return true;
}
catch (Exception e)
{
DebugPrint("TryInvokeMember Exception: " + e);
result = null;
return false;
}
}

// Converting an object to a specified type.
public override bool TryConvert(ConvertBinder binder, out object result)
{
// Converting to string.
if (binder.Type == typeof(String))
{
result = "DynamicViewModel with " +
((properties.Count > 1) ? ("" + properties.Count + " Dynamic Properties") :
("" + properties.Count + " Dynamic Property"));
return true;
}

// In case of any other type, the binder
// attempts to perform the conversion itself.
// In most cases, a run-time exception is thrown.
return base.TryConvert(binder, out result);
}

public override IEnumerable<String> GetDynamicMemberNames()
{
return properties.Keys.Cast<String>() ;
}

public override string ToString()
{
return "DynamicViewModel with " +
((properties.Count > 1) ? ("" + properties.Count + " Dynamic Properties") :
("" + properties.Count + " Dynamic Property"));
}

public bool Remove(string name)
{
if (properties.ContainsKey(name))
{
properties.Remove(name);
return true;
}
else
{
return false;
}
}

public void Print()
{
foreach (DictionaryEntry pair in properties)
{
if (pair.Value != null)
{
Console.WriteLine(pair.Key + " \t" + pair.Value + " \t" + pair.Value.GetType());
}
else
{
Console.WriteLine(pair.Key + " \t" + pair.Value + " \tNull Value");
}

}

if (properties.Count == 0)
Console.WriteLine("No elements in the dictionary.");
}

protected void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}

protected void DebugPrint(String s)
{
if (debugLevel == 1)
{
Console.WriteLine(s);
}
}
}

3b. Add DynamicViewModel.cs to Powershell

$csharp1=Get-Content (Join-Path $path "DynamicViewModel.cs") -Raw
Add-Type -TypeDefinition $csharp1

Posted in Uncategorized | Leave a comment

Write a GUI in Powershell – Part 2

2. Convert XAML to powershell

[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$xaml = Get-Content -Raw -Path (Join-Path $path "autoshutdown.xaml")

#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
catch{Write-Host "Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta, invalid XAML code was encountered."; exit}

$manager = New-Object System.Xml.XmlNamespaceManager $xaml.NameTable;
$manager.AddNamespace("xaml", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
$manager.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml");
$xaml.SelectNodes("//*[@x:Name]", $manager ) | %{Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}

Posted in C#, Powershell, XAML | Leave a comment