diff --git a/bindings/powershell/Invoke-Keystone.ps1 b/bindings/powershell/Invoke-Keystone.ps1
deleted file mode 100644
index e3f4226b8c978eddd4ec806ddc5a251a80da5f77..0000000000000000000000000000000000000000
--- a/bindings/powershell/Invoke-Keystone.ps1
+++ /dev/null
@@ -1,327 +0,0 @@
-function Invoke-Keystone {
-<#
-.SYNOPSIS
-	Powershell wrapper for Keystone (using inline C#).
-
-	In effect the function directly parses the Keystone dll so it can support any
-	features implemented by Keystone so long as function calls are prototyped in C#.
-
-.DESCRIPTION
-	Author: Ruben Boonen (@FuzzySec)
-	License: BSD 3-Clause
-	Required Dependencies: None
-	Optional Dependencies: None
-
-.EXAMPLE
-
-	# Support for multi-line code blocks
-	PS C:\> $Code = @"
-	>> sub esp, 200
-	>> pop eax
-	>> pop ecx
-	>> ret
-	>> "@
-	PS C:\> Invoke-Keystone -Architecture X86 -Mode 32 -Code $Code
-	
-	Bytes        : 9
-	Instructions : 4
-	PSArray      : {0x81, 0xEC, 0xC8, 0x00...}
-	CArray       : {\x81, \xEC, \xC8, \x00...}
-	RawArray     : {81, EC, C8, 00...}
-
-.EXAMPLE
-
-	# Invoke-Keystone emits objects
-	PS C:\> $Code = @"
-	>> sub esp, 200
-	>> pop eax
-	>> pop ecx
-	>> ret
-	>> "@
-	PS C:\> $Object = Invoke-Keystone -Architecture X86 -Mode 32 -Code $Code
-	PS C:\> $Object.RawArray -join ""
-	81ECC80000005859C3
-	PS C:\> $Object.CArray -join ""
-	\x81\xEC\xC8\x00\x00\x00\x58\x59\xC3
-	PS C:\> "`$Shellcode = {" + $($Object.PSArray -join ", ") + "}"
-	$Shellcode = {0x81, 0xEC, 0xC8, 0x00, 0x00, 0x00, 0x58, 0x59, 0xC3}
-
-#>
-
-	param(
-        [Parameter(Mandatory = $True)]
-        [ValidateSet(
-			'ARM',
-			'ARM64',
-			'MIPS',
-			'X86',
-			'PPC',
-			'SPARC',
-			'SYSZ',
-			'HEXAGON',
-			'MAX')
-		]
-        [String]$Architecture,
-		
-        [Parameter(Mandatory = $True)]
-        [ValidateSet(
-			'Little_Endian',
-			'Big_Endian',
-			'ARM',
-			'THUMB',
-			'V8',
-			'MICRO',
-			'MIPS3',
-			'MIPS32R6',
-			'MIPS32',
-			'MIPS64',
-			'16',
-			'32',
-			'64',
-			'PPC32',
-			'PPC64',
-			'QPX',
-			'SPARC32',
-			'SPARC64',
-			'V9')
-		]
-        [String]$Mode,
-
-		[Parameter(Mandatory = $True)]
-		[string]$Code,
-
-		[Parameter(Mandatory = $False)]
-		[String]$Syntax = "Intel"
-    )
-
-	Add-Type -TypeDefinition @"
-	using System;
-	using System.Diagnostics;
-	using System.Runtime.InteropServices;
-	using System.Security.Principal;
-
-	[Flags]
-	public enum ks_err : int
-	{
-		KS_ERR_OK = 0,      /// No error: everything was fine
-		KS_ERR_NOMEM,       /// Out-Of-Memory error: ks_open(), ks_emulate()
-		KS_ERR_ARCH,        /// Unsupported architecture: ks_open()
-		KS_ERR_HANDLE,      /// Invalid handle
-		KS_ERR_MODE,        /// Invalid/unsupported mode: ks_open()
-		KS_ERR_VERSION,     /// Unsupported version (bindings)
-		KS_ERR_OPT_INVALID, /// Unsupported option
-		
-		/// generic input assembly errors - parser specific
-		KS_ERR_ASM_EXPR_TOKEN = 128,        /// unknown token in expression
-		KS_ERR_ASM_DIRECTIVE_VALUE_RANGE,   /// literal value out of range for directive
-		KS_ERR_ASM_DIRECTIVE_ID,            /// expected identifier in directive
-		KS_ERR_ASM_DIRECTIVE_TOKEN,         /// unexpected token in directive
-		KS_ERR_ASM_DIRECTIVE_STR,           /// expected string in directive
-		KS_ERR_ASM_DIRECTIVE_COMMA,         /// expected comma in directive
-		KS_ERR_ASM_DIRECTIVE_RELOC_NAME,    /// expected relocation name in directive
-		KS_ERR_ASM_DIRECTIVE_RELOC_TOKEN,   /// unexpected token in .reloc directive
-		KS_ERR_ASM_DIRECTIVE_FPOINT,        /// invalid floating point in directive
-		KS_ERR_ASM_DIRECTIVE_UNKNOWN,       /// unknown directive
-		KS_ERR_ASM_DIRECTIVE_EQU,           /// invalid equal directive
-		KS_ERR_ASM_DIRECTIVE_INVALID,       /// (generic) invalid directive
-		KS_ERR_ASM_VARIANT_INVALID,         /// invalid variant
-		KS_ERR_ASM_EXPR_BRACKET,            /// brackets expression not supported on this target
-		KS_ERR_ASM_SYMBOL_MODIFIER,         /// unexpected symbol modifier following '@'
-		KS_ERR_ASM_SYMBOL_REDEFINED,        /// invalid symbol redefinition
-		KS_ERR_ASM_SYMBOL_MISSING,          /// cannot find a symbol
-		KS_ERR_ASM_RPAREN,                  /// expected ')' in parentheses expression
-		KS_ERR_ASM_STAT_TOKEN,              /// unexpected token at start of statement
-		KS_ERR_ASM_UNSUPPORTED,             /// unsupported token yet
-		KS_ERR_ASM_MACRO_TOKEN,             /// unexpected token in macro instantiation
-		KS_ERR_ASM_MACRO_PAREN,             /// unbalanced parentheses in macro argument
-		KS_ERR_ASM_MACRO_EQU,               /// expected '=' after formal parameter identifier
-		KS_ERR_ASM_MACRO_ARGS,              /// too many positional arguments
-		KS_ERR_ASM_MACRO_LEVELS_EXCEED,     /// macros cannot be nested more than 20 levels deep
-		KS_ERR_ASM_MACRO_STR,               /// invalid macro string
-		KS_ERR_ASM_MACRO_INVALID,           /// invalid macro (generic error)
-		KS_ERR_ASM_ESC_BACKSLASH,           /// unexpected backslash at end of escaped string
-		KS_ERR_ASM_ESC_OCTAL,               /// invalid octal escape sequence  (out of range)
-		KS_ERR_ASM_ESC_SEQUENCE,            /// invalid escape sequence (unrecognized character)
-		KS_ERR_ASM_ESC_STR,                 /// broken escape string
-		KS_ERR_ASM_TOKEN_INVALID,           /// invalid token
-		KS_ERR_ASM_INSN_UNSUPPORTED,        /// this instruction is unsupported in this mode
-		KS_ERR_ASM_FIXUP_INVALID,           /// invalid fixup
-		KS_ERR_ASM_LABEL_INVALID,           /// invalid label
-		KS_ERR_ASM_FRAGMENT_INVALID,        /// invalid fragment
-		
-		/// generic input assembly errors - architecture specific
-		KS_ERR_ASM_INVALIDOPERAND = 512,
-		KS_ERR_ASM_MISSINGFEATURE,
-		KS_ERR_ASM_MNEMONICFAIL,
-	}
-	
-	public static class Keystone
-	{
-		[DllImport("keystone.dll")]
-		public static extern ks_err ks_open(
-			int arch,
-			int mode,
-			ref IntPtr handle);
-
-		[DllImport("keystone.dll")]
-		public static extern ks_err ks_option(
-			IntPtr handle,
-			int mode,
-			uint value);
-
-		[DllImport("keystone.dll")]
-		public static extern int ks_asm(
-			IntPtr handle,
-			String assembly,
-			ulong address,
-			ref IntPtr encoding,
-			ref uint encoding_size,
-			ref uint stat_count);
-
-		[DllImport("keystone.dll")]
-		public static extern ks_err ks_errno(
-			IntPtr handle);
-
-		[DllImport("keystone.dll")]
-		public static extern ks_err ks_close(
-			IntPtr handle);
-
-		[DllImport("keystone.dll")]
-		public static extern void ks_free(
-			IntPtr handle);
-	}
-"@
-
-	# Architecture -> int
-	New-Variable -Option Constant -Name ks_arch -Value @{
-		"ARM"   = 1
-		"ARM64" = 2
-		"MIPS"  = 3
-		"X86"   = 4
-		# unsupported -> keystone.h
-		"PPC"   = 5
-		"SPARC" = 6
-		"SYSZ"  = 7
-		"HEXAGON" = 8
-		"MAX"   = 9
-	}
-
-	# Mode -> int
-	New-Variable -Option Constant -Name ks_mode -Value @{
-		"Little_Endian" = 0
-		"Big_Endian"    = 1073741824
-		"ARM"           = 1
-		"THUMB"         = 16
-		"V8"            = 64
-		"MICRO"         = 16
-		"MIPS3"         = 32
-		"MIPS32R6"      = 64
-		"MIPS32"        = 4
-		"MIPS64"        = 8
-		"16"            = 2
-		"32"            = 4
-		"64"            = 8
-		"PPC32"         = 4
-		"PPC64"         = 8
-		"QPX"           = 16
-		"SPARC32"       = 4
-		"SPARC64"       = 8
-		"V9"            = 16
-	}
-
-	New-Variable -Option Constant -Name ks_opt_value -Value @{
-		"Intel" = 1
-		"ATT"   = 2
-		"NASM"  = 4
-		# unsupported -> keystone.h
-		"MASM"  = 8
-		"GAS"   = 16
-	}
-
-	# Asm Handle
-	$AsmHandle = [IntPtr]::Zero
-
-	# Initialize Keystone with ks_open()
-	# Add a try/catch here to handle missing DLL
-	try {
-		$CallResult = [Keystone]::ks_open($ks_arch[$Architecture],$ks_mode[$Mode],[ref]$AsmHandle)
-	} catch {
-		if ($Error[0].FullyQualifiedErrorId -eq "DllNotFoundException") {
-			echo "`n[!] Missing Keystone DLL"
-		} else {
-			echo "`n[!] Exception: $($Error[0].FullyQualifiedErrorId)"
-		}
-		echo "[>] Quitting..`n"
-		Return
-	}
-	if ($CallResult -ne "KS_ERR_OK") {
-		if ($CallResult -eq "KS_ERR_MODE"){
-			echo "`n[!] Invalid Architecture/Mode combination"
-			echo "[>] Quitting..`n"
-		} else {
-			echo "`n[!] cs_open error: $CallResult"
-			echo "[>] Quitting..`n"
-		}
-		Return
-	}
-
-	# Only one ks_opt_type -> KS_OPT_SYNTAX = 1
-	$CallResult = [Keystone]::ks_option($AsmHandle, 1, $ks_opt_value[$Syntax])
-	if ($CallResult -ne "KS_ERR_OK") {
-		echo "`n[!] ks_option error: $CallResult"
-		echo "[>] Quitting..`n"
-		$CallResult = [Keystone]::ks_close($AsmHandle)
-		Return
-	}
-
-	# Result variables
-	$Encoded = [IntPtr]::Zero
-	[int]$Encoded_size = 0
-	[int]$Stat_count = 0
-
-	# Assemble instructions
-	$CallResult = [Keystone]::ks_asm($AsmHandle, $Code, 0, [ref]$Encoded, [ref]$Encoded_size, [ref]$stat_count)
-
-	if ($CallResult -ne 0) {
-		echo "`n[!] ks_asm error: $([Keystone]::ks_errno($AsmHandle))"
-		echo "[>] Quitting..`n"
-		$CallResult = [Keystone]::ks_close($AsmHandle)
-		Return
-	} else {
-		$BufferOffset = $Encoded.ToInt64()
-
-		if ($Encoded_size -gt 0) {
-			# PS/C# hex array
-			$PSArray = @()
-			# C-style hex array
-			$CArray = @()
-			# Raw hex array
-			$RawArray = @()
-			for ($i=0; $i -lt $Encoded_size; $i++) {
-				$PSArray += echo "0x$("{0:X2}" -f $([Runtime.InteropServices.Marshal]::ReadByte($BufferOffset)))"
-				$CArray += echo "\x$("{0:X2}" -f $([Runtime.InteropServices.Marshal]::ReadByte($BufferOffset)))"
-				$RawArray += echo "$("{0:X2}" -f $([Runtime.InteropServices.Marshal]::ReadByte($BufferOffset)))"
-				$BufferOffset = $BufferOffset+1
-			}
-			# Result Object
-			$HashTable = @{
-				Bytes = $Encoded_size
-				Instructions = $stat_count
-				PSArray = $PSArray
-				CArray = $CArray
-				RawArray = $RawArray
-			}
-			New-Object PSObject -Property $HashTable |Select-Object Bytes,Instructions,PSArray,CArray,RawArray
-
-			# Clean up!
-			[Keystone]::ks_free($Encoded)
-			$CallResult = [Keystone]::ks_close($AsmHandle)
-		} else {
-			echo "`n[!] No bytes assembled"
-			echo "[>] Quitting..`n"
-			$CallResult = [Keystone]::ks_close($AsmHandle)
-			Return
-		}
-	}
-
-}
\ No newline at end of file
diff --git a/bindings/powershell/Keystone/Const/ks_arch_cons.cs b/bindings/powershell/Keystone/Const/ks_arch_cons.cs
new file mode 100755
index 0000000000000000000000000000000000000000..fa1055fb3502a7d1b3f303e535e3d604ff620129
--- /dev/null
+++ b/bindings/powershell/Keystone/Const/ks_arch_cons.cs
@@ -0,0 +1,9 @@
+KS_ARCH_ARM = 1,
+KS_ARCH_ARM64,
+KS_ARCH_MIPS,
+KS_ARCH_X86,
+KS_ARCH_PPC,
+KS_ARCH_SPARC,
+KS_ARCH_SYSTEMZ,
+KS_ARCH_HEXAGON,
+KS_ARCH_MAX,
\ No newline at end of file
diff --git a/bindings/powershell/Keystone/Const/ks_err_cons.cs b/bindings/powershell/Keystone/Const/ks_err_cons.cs
new file mode 100755
index 0000000000000000000000000000000000000000..6387facf2e61b58d4b06424a56f5e2be4adbefcf
--- /dev/null
+++ b/bindings/powershell/Keystone/Const/ks_err_cons.cs
@@ -0,0 +1,46 @@
+KS_ERR_OK = 0,
+KS_ERR_NOMEM,
+KS_ERR_ARCH,
+KS_ERR_HANDLE,
+KS_ERR_MODE,
+KS_ERR_VERSION,
+KS_ERR_OPT_INVALID,
+KS_ERR_ASM_EXPR_TOKEN = 128,
+KS_ERR_ASM_DIRECTIVE_VALUE_RANGE,
+KS_ERR_ASM_DIRECTIVE_ID,
+KS_ERR_ASM_DIRECTIVE_TOKEN,
+KS_ERR_ASM_DIRECTIVE_STR,
+KS_ERR_ASM_DIRECTIVE_COMMA,
+KS_ERR_ASM_DIRECTIVE_RELOC_NAME,
+KS_ERR_ASM_DIRECTIVE_RELOC_TOKEN,
+KS_ERR_ASM_DIRECTIVE_FPOINT,
+KS_ERR_ASM_DIRECTIVE_UNKNOWN,
+KS_ERR_ASM_DIRECTIVE_EQU,
+KS_ERR_ASM_DIRECTIVE_INVALID,
+KS_ERR_ASM_VARIANT_INVALID,
+KS_ERR_ASM_EXPR_BRACKET,
+KS_ERR_ASM_SYMBOL_MODIFIER,
+KS_ERR_ASM_SYMBOL_REDEFINED,
+KS_ERR_ASM_SYMBOL_MISSING,
+KS_ERR_ASM_RPAREN,
+KS_ERR_ASM_STAT_TOKEN,
+KS_ERR_ASM_UNSUPPORTED,
+KS_ERR_ASM_MACRO_TOKEN,
+KS_ERR_ASM_MACRO_PAREN,
+KS_ERR_ASM_MACRO_EQU,
+KS_ERR_ASM_MACRO_ARGS,
+KS_ERR_ASM_MACRO_LEVELS_EXCEED,
+KS_ERR_ASM_MACRO_STR,
+KS_ERR_ASM_MACRO_INVALID,
+KS_ERR_ASM_ESC_BACKSLASH,
+KS_ERR_ASM_ESC_OCTAL,
+KS_ERR_ASM_ESC_SEQUENCE,
+KS_ERR_ASM_ESC_STR,
+KS_ERR_ASM_TOKEN_INVALID,
+KS_ERR_ASM_INSN_UNSUPPORTED,
+KS_ERR_ASM_FIXUP_INVALID,
+KS_ERR_ASM_LABEL_INVALID,
+KS_ERR_ASM_FRAGMENT_INVALID,
+KS_ERR_ASM_INVALIDOPERAND = 512,
+KS_ERR_ASM_MISSINGFEATURE,
+KS_ERR_ASM_MNEMONICFAIL,
\ No newline at end of file
diff --git a/bindings/powershell/Keystone/Const/ks_mode_cons.cs b/bindings/powershell/Keystone/Const/ks_mode_cons.cs
new file mode 100755
index 0000000000000000000000000000000000000000..97f64f561ef47eee4770faff83f2f4a4493d2cf5
--- /dev/null
+++ b/bindings/powershell/Keystone/Const/ks_mode_cons.cs
@@ -0,0 +1,19 @@
+KS_MODE_LITTLE_ENDIAN = 0,
+KS_MODE_BIG_ENDIAN = 1 << 30,
+KS_MODE_ARM = 1 << 0,
+KS_MODE_THUMB = 1 << 4,
+KS_MODE_V8 = 1 << 6,
+KS_MODE_MICRO = 1 << 4,
+KS_MODE_MIPS3 = 1 << 5,
+KS_MODE_MIPS32R6 = 1 << 6,
+KS_MODE_MIPS32 = 1 << 2,
+KS_MODE_MIPS64 = 1 << 3,
+KS_MODE_16 = 1 << 1,
+KS_MODE_32 = 1 << 2,
+KS_MODE_64 = 1 << 3,
+KS_MODE_PPC32 = 1 << 2,
+KS_MODE_PPC64 = 1 << 3,
+KS_MODE_QPX = 1 << 4,
+KS_MODE_SPARC32 = 1 << 2,
+KS_MODE_SPARC64 = 1 << 3,
+KS_MODE_V9 = 1 << 4,
\ No newline at end of file
diff --git a/bindings/powershell/Keystone/Const/ks_opt_value_cons.cs b/bindings/powershell/Keystone/Const/ks_opt_value_cons.cs
new file mode 100755
index 0000000000000000000000000000000000000000..f904ad2e9e01f37d639f2a1ccbec3be0de30b118
--- /dev/null
+++ b/bindings/powershell/Keystone/Const/ks_opt_value_cons.cs
@@ -0,0 +1,5 @@
+KS_OPT_SYNTAX_INTEL = 1 << 0,
+KS_OPT_SYNTAX_ATT   = 1 << 1,
+KS_OPT_SYNTAX_NASM  = 1 << 2,
+KS_OPT_SYNTAX_MASM  = 1 << 3,
+KS_OPT_SYNTAX_GAS   = 1 << 4,
\ No newline at end of file
diff --git a/bindings/powershell/Keystone/Keystone.psd1 b/bindings/powershell/Keystone/Keystone.psd1
new file mode 100755
index 0000000000000000000000000000000000000000..be0172d56c26a970dfe7021a02cd04c51e9daa13
--- /dev/null
+++ b/bindings/powershell/Keystone/Keystone.psd1
@@ -0,0 +1,25 @@
+@{
+# Script module or binary module file associated with this manifest.
+ModuleToProcess = 'Keystone.psm1'
+
+# Version number of this module.
+ModuleVersion = '0.0.0.1'
+
+# ID used to uniquely identify this module
+GUID = 'd34db33f-7f65-4681-9cfb-0cf4929a8e68'
+
+# Author of this module
+Author = 'Ruben Boonen'
+
+# Copyright statement for this module
+Copyright = 'see COPYING'
+
+# Description of the functionality provided by this module
+Description = 'Keystone Engine Binding Module'
+
+# Minimum version of the Windows PowerShell engine required by this module
+PowerShellVersion = '2.0'
+
+# Functions to export from this module
+FunctionsToExport = '*'
+}
diff --git a/bindings/powershell/Keystone/Keystone.psm1 b/bindings/powershell/Keystone/Keystone.psm1
new file mode 100755
index 0000000000000000000000000000000000000000..a34bfefe1924c7d23e6cf24917e59a31b44133a5
--- /dev/null
+++ b/bindings/powershell/Keystone/Keystone.psm1
@@ -0,0 +1,304 @@
+function Get-KeystoneAssembly {
+<#
+.SYNOPSIS
+	Powershell wrapper for Keystone (using inline C#).
+
+.DESCRIPTION
+	Author: Ruben Boonen (@FuzzySec)
+	License: BSD 3-Clause
+	Required Dependencies: None
+	Optional Dependencies: None
+
+.PARAMETER Architecture
+	Architecture type.
+
+.PARAMETER Mode
+	Mode type.
+
+.PARAMETER Code
+	Assembly string, use ";" or multi-line variables for instruction separation.
+
+.PARAMETER Syntax
+	Syntax for input assembly.
+
+.PARAMETER Version
+	Print ASCII version banner.
+
+.EXAMPLE
+
+	# Support for multi-line code blocks
+	PS C:\> $Code = @"
+	>> sub esp, 200
+	>> pop eax
+	>> pop ecx
+	>> ret
+	>> "@
+	PS C:\> Get-KeystoneAssembly -Architecture X86 -Mode 32 -Code $Code
+
+	Bytes        : 9
+	Instructions : 4
+	PSArray      : {0x81, 0xEC, 0xC8, 0x00...}
+	CArray       : {\x81, \xEC, \xC8, \x00...}
+	RawArray     : {81, EC, C8, 00...}
+
+.EXAMPLE
+
+	# Get-KeystoneAssembly emits objects
+	PS C:\> $Code = @"
+	>> sub esp, 200
+	>> pop eax
+	>> pop ecx
+	>> ret
+	>> "@
+	PS C:\> $Object = Get-KeystoneAssembly -Architecture X86 -Mode 32 -Code $Code
+	PS C:\> $Object.RawArray -join ""
+	81ECC80000005859C3
+	PS C:\> $Object.CArray -join ""
+	\x81\xEC\xC8\x00\x00\x00\x58\x59\xC3
+	PS C:\> "`$Shellcode = {" + $($Object.PSArray -join ", ") + "}"
+	$Shellcode = {0x81, 0xEC, 0xC8, 0x00, 0x00, 0x00, 0x58, 0x59, 0xC3}
+
+#>
+
+	param(
+        [Parameter(ParameterSetName='Keystone', Mandatory = $True)]
+        [ValidateSet(
+			'KS_ARCH_ARM',
+			'KS_ARCH_ARM64',
+			'KS_ARCH_MIPS',
+			'KS_ARCH_X86',
+			'KS_ARCH_PPC',
+			'KS_ARCH_SPARC',
+			'KS_ARCH_SYSTEMZ',
+			'KS_ARCH_HEXAGON',
+			'KS_ARCH_MAX')
+		]
+        [String]$Architecture,
+		
+        [Parameter(ParameterSetName='Keystone', Mandatory = $True)]
+        [ValidateSet(
+			'KS_MODE_LITTLE_ENDIAN',
+			'KS_MODE_BIG_ENDIAN',
+			'KS_MODE_ARM',
+			'KS_MODE_THUMB',
+			'KS_MODE_V8',
+			'KS_MODE_MICRO',
+			'KS_MODE_MIPS3',
+			'KS_MODE_MIPS32R6',
+			'KS_MODE_MIPS32',
+			'KS_MODE_MIPS64',
+			'KS_MODE_16',
+			'KS_MODE_32',
+			'KS_MODE_64',
+			'KS_MODE_PPC32',
+			'KS_MODE_PPC64',
+			'KS_MODE_QPX',
+			'KS_MODE_SPARC32',
+			'KS_MODE_SPARC64',
+			'KS_MODE_V9')
+		]
+        [String]$Mode,
+
+		[Parameter(ParameterSetName='Keystone', Mandatory = $True)]
+		[ValidateNotNullOrEmpty()]
+		[string]$Code,
+
+		[Parameter(ParameterSetName='Keystone', Mandatory = $False)]
+        [ValidateSet(
+			'KS_OPT_SYNTAX_INTEL',
+			'KS_OPT_SYNTAX_ATT',
+			'KS_OPT_SYNTAX_NASM',
+			'KS_OPT_SYNTAX_MASM',
+			'KS_OPT_SYNTAX_GAS')
+		]
+		[String]$Syntax = "KS_OPT_SYNTAX_INTEL",
+
+		[Parameter(ParameterSetName='Version', Mandatory = $False)]
+		[switch]$Version = $null
+    )
+
+	if ($Version){
+		$Banner = @"
+
+                ;#                 
+             #########             
+           ######""   ;;           
+     ###";#### ;##############     
+   ##### ### ##""   "## ""######   
+   #### ###           ""### "###   
+   #### ##               "### "#   
+   "### \#               ; ####    
+    "### "               ##"####   
+   ## \###               ## ####   
+   #### "###;           ### ####   
+   ######## "#"   ;### ###"#####   
+     "#############" ####"/##"     
+           "    ;#######           
+             "#######"             
+                 #                 	
+                                     
+    -=[Keystone Engine v0.9.1]=-
+
+"@
+		# Mmm ASCII version banner!
+		$Banner
+		Return
+	}
+
+	# Compatibility for PS v2 / PS v3+
+	if(!$PSScriptRoot) {
+		$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
+	}
+	
+	# Set the keystone DLL path
+	if ([IntPtr]::Size -eq 4){
+		$DllPath = $($PSScriptRoot + '\Lib\Keystone-0.9.1\x86\keystone.dll').Replace('\','\\')
+	} else {
+		$DllPath = $($PSScriptRoot + '\Lib\Keystone-0.9.1\x64\keystone.dll').Replace('\','\\')
+	}
+
+	# Load C# constants
+	$ks_err = Get-Content $($PSScriptRoot + '\Const\ks_err_cons.cs')
+	$ks_arch = Get-Content $($PSScriptRoot + '\Const\ks_arch_cons.cs')
+	$ks_mode = Get-Content $($PSScriptRoot + '\Const\ks_mode_cons.cs')
+	$ks_opt_value = Get-Content $($PSScriptRoot + '\Const\ks_opt_value_cons.cs')
+
+	# Inline C# to parse the unmanaged keystone DLL
+	Add-Type -TypeDefinition @"
+	using System;
+	using System.Diagnostics;
+	using System.Runtime.InteropServices;
+	using System.Security.Principal;
+
+	public enum ks_err : int
+	{
+		$ks_err
+	}
+
+	public enum ks_arch : int
+	{
+		$ks_arch
+	}
+
+	public enum ks_mode : int
+	{
+		$ks_mode
+	}
+
+	public enum ks_opt_value : uint
+	{
+		$ks_opt_value
+	}
+
+	public static class Keystone
+	{
+		[DllImport("$DllPath")]
+		public static extern ks_err ks_open(
+			ks_arch arch,
+			ks_mode mode,
+			ref IntPtr handle);
+
+		[DllImport("$DllPath")]
+		public static extern ks_err ks_option(
+			IntPtr handle,
+			int mode,
+			ks_opt_value value);
+
+		[DllImport("$DllPath")]
+		public static extern int ks_asm(
+			IntPtr handle,
+			String assembly,
+			ulong address,
+			ref IntPtr encoding,
+			ref uint encoding_size,
+			ref uint stat_count);
+
+		[DllImport("$DllPath")]
+		public static extern ks_err ks_errno(
+			IntPtr handle);
+
+		[DllImport("$DllPath")]
+		public static extern ks_err ks_close(
+			IntPtr handle);
+
+		[DllImport("$DllPath")]
+		public static extern void ks_free(
+			IntPtr handle);
+	}
+"@
+
+	# Asm Handle
+	$AsmHandle = [IntPtr]::Zero
+
+	# Initialize Keystone with ks_open()
+	$CallResult = [Keystone]::ks_open($Architecture,$Mode,[ref]$AsmHandle)
+	if ($CallResult -ne "KS_ERR_OK") {
+		if ($CallResult -eq "KS_ERR_MODE"){
+			echo "`n[!] Invalid Architecture/Mode combination"
+			echo "[>] Quitting..`n"
+		} else {
+			echo "`n[!] cs_open error: $CallResult"
+			echo "[>] Quitting..`n"
+		}
+		Return
+	}
+
+	# Only one ks_opt_type -> KS_OPT_SYNTAX = 1
+	$CallResult = [Keystone]::ks_option($AsmHandle, 1, $Syntax)
+	if ($CallResult -ne "KS_ERR_OK") {
+		echo "`n[!] ks_option error: $CallResult"
+		echo "[>] Quitting..`n"
+		$CallResult = [Keystone]::ks_close($AsmHandle)
+		Return
+	}
+
+	# Result variables
+	$Encoded = [IntPtr]::Zero
+	[int]$Encoded_size = 0
+	[int]$Stat_count = 0
+
+	# Assemble instructions
+	$CallResult = [Keystone]::ks_asm($AsmHandle, $Code, 0, [ref]$Encoded, [ref]$Encoded_size, [ref]$stat_count)
+
+	if ($CallResult -ne 0) {
+		echo "`n[!] ks_asm error: $([Keystone]::ks_errno($AsmHandle))"
+		echo "[>] Quitting..`n"
+		$CallResult = [Keystone]::ks_close($AsmHandle)
+		Return
+	} else {
+		$BufferOffset = $Encoded.ToInt64()
+
+		if ($Encoded_size -gt 0) {
+			# PS/C# hex array
+			$PSArray = @()
+			# C-style hex array
+			$CArray = @()
+			# Raw hex array
+			$RawArray = @()
+			for ($i=0; $i -lt $Encoded_size; $i++) {
+				$PSArray += echo "0x$("{0:X2}" -f $([Runtime.InteropServices.Marshal]::ReadByte($BufferOffset)))"
+				$CArray += echo "\x$("{0:X2}" -f $([Runtime.InteropServices.Marshal]::ReadByte($BufferOffset)))"
+				$RawArray += echo "$("{0:X2}" -f $([Runtime.InteropServices.Marshal]::ReadByte($BufferOffset)))"
+				$BufferOffset = $BufferOffset+1
+			}
+			# Result Object
+			$HashTable = @{
+				Bytes = $Encoded_size
+				Instructions = $stat_count
+				PSArray = $PSArray
+				CArray = $CArray
+				RawArray = $RawArray
+			}
+			New-Object PSObject -Property $HashTable |Select-Object Bytes,Instructions,PSArray,CArray,RawArray
+
+			# Clean up!
+			[Keystone]::ks_free($Encoded)
+			$CallResult = [Keystone]::ks_close($AsmHandle)
+		} else {
+			echo "`n[!] No bytes assembled"
+			echo "[>] Quitting..`n"
+			$CallResult = [Keystone]::ks_close($AsmHandle)
+			Return
+		}
+	}
+}
\ No newline at end of file
diff --git a/bindings/powershell/README b/bindings/powershell/README
index b01dd43e54cb7a8ce1db5f66a9c79e67c2840869..06ef4fb93c7c3af7af964c59428d53313723d07f 100644
--- a/bindings/powershell/README
+++ b/bindings/powershell/README
@@ -1,26 +1,16 @@
 Usage
 
-Invoke-Keystone requires an architecture appropriate (x32/64) compiled Keystone DLL.
-A pre-compiled version can be found on the Keystone download page at the following
-URL:
-
-  * http://www.keystone-engine.org/download/
-
-Once downloaded, the DLL should be placed in a directory which is part of the SafeDllSearchMode search order. In practice, any folder which is part of the Windows PATH environment variable will work.
-
-The Invoke-Keystone function itself can be initialized using one of the following methods:
-
-  * Script dot sourcing:
+To use the PowerShell binding, the Keystone folder should be added to one of the PowerShell module directories:
 
-     PS C:\> . .\Invoke-Keystone.ps1
+  # Global PSModulePath path
+  %Windir%\System32\WindowsPowerShell\v1.0\Modules
 
-  * Adding the script to one of the PowerShell module directories:
+  # User PSModulePath path
+  %UserProfile%\Documents\WindowsPowerShell\Modules
 
-     # Global PSModulePath path
-     %Windir%\System32\WindowsPowerShell\v1.0\Modules
+Once this is done the module can be initialized by typing “Import-Module Keystone” in a new PowerShell terminal. Further information on the usage of the binding can be obtained with the following command:
 
-     # User PSModulePath path
-     %UserProfile%\Documents\WindowsPowerShell\Modules
+  Get-Help Get-KeystoneAssembly -Full
 
 Notes