Powershell - Scheduled Tasks, language independence, Win 7+ - powershell

I know there has to be an easy solution to this but I have been searching for two days now with no luck.
Basic goal:
I want to query (and set) the state of Scheduled Defrag using PowerShell
Limitations: Must be able to work when run with the system set to any language, Must not require installing any additional software, packs, etc (ie clean system), Must be able to run on any system Windows 7+ (ideally even earlier)
Issues:
I can get the state using 'schtasks /query /TN
'\Microsoft\Windows\Defrag\ScheduledDefrag'' but this is (a)
directory language dependent, and more importantly (b) returns
everything as a string of some sort, meaning state is something
like 'Disabled'.. in English. But every language returns its own
word for 'Disabled', in its own character code, meaning hard-coding
over a hundred languages x the number of options
Windows 7 does not recognize Get-ScheduledTask (seems to be
Win8+), even if it did not sure how to query 'Disabled' as a state
without using the actual word
I have to be missing something very basic but all I am finding are suggestions to install Powershell packs, and responses dealing specifically with English. Any suggestions?

Related

Powershell - how to replace OS Version number with other OS Version (2008R2 becomes a 2016)

I need you'r help, I searched everywhere but couldn't find anything on the subject.
ACTUAL
A programm check my server version with this command :
[System.Environment]::OSVersion.Version.Major
6
The result is 6, this is perfectly good because it's a 2008R2 server.
EXCPECTED SITUATION
[System.Environment]::OSVersion.Version.Major
10
I need this same command to give a result equivalent to 10.
The objective is to deceive the program to make it believe that the server is a windows server 2016 but it is a windows 2008R2 server.
I don't need to just replace the string or other non persistant solution.
I need to change this value with a powershell script (or other non executable script) before launch the program that checks the OSversion.
The value is stored here, it seems to be directly related to the Common Language Runtime, i think i need to modify
So I think we should be able to modify a value in the CLR, but I don't know how to do it, and even if it is possible.
enter image description here

Return True / False values when scanning a ps1 file from AMSI?

I would like to write a small script as part of a pentest that validates and outputs whether Windows Defender Antimalware Scan Interface (AMSI) flags the file or not. Since I need a powershell script to do the scanning best, but I don't know enough about the language to write such one, I resorted to the PSAmsi tool. Anyway, that's what I tried...
However, I constantly have the problem that PSAmsi cannot work because defender prevents it from doing so. If I turn off Defender, PSAmsi works, but it aborts with the error message that no AMSI was detected, which I had to deactivate with Defender before...,
Also I get errors all the time and when it works, PSAmsi always returns false, even with malicious files, which doesn't work like that...
Does anyone know about PSAmsi or can give me advice
With kind regards, Luke

Change Language Per-PowerShell Session

I'm running a PowerShell script across thousands of computers globally and due to our machines having many different languages (Spanish, French, German, etc.) some of the commands aren't working and having to write code multiple times to suite each locale is a sin when I could have just written the code once. As just one example, I'm trying to check who the group members are of the local administrators group on workstations.
Example Command in English
$localGroupAdmins = (Get-LocalGroupMember -SID "S-1-5-32-544" | Where-Object {$_.ObjectClass -eq "Group"}).Name
Need to specify the SID of the local administrators group since that word is also in another language (no problem for now). Issue really is that the object class is "grupo" for Spanish machines, "Gruppe" for German machines and so on so doing the Where-Object {$_.ObjectClass... is not consistent and of course fails.
Therefore, how can I get this over to English for just the PowerShell session without impacting the user and changing their UI? Last thing I want is to have calls to the Help Desk stating their computer is now in English.
I've tried links below but nothing works. Also, script runs in system context if that matters.
Temporarily change powershell language to English?
Forcing PowerShell errors output in English on localized systems
https://community.spiceworks.com/topic/560456-how-to-change-powershell-script-errors-to-english

PowerShell: best way to ensure function name uniqueness?

What's the best way to ensure your PowerShell function name is unique? The standard since version 1 is to put in a short unique id after the verb dash and before the noun. For example, with my initials I could create function Get-DWServer; this is fine until someone creates a function in a different module for getting an object reference to a datawarehouse and uses the same function name. Two or three letters just isn't sufficient but more than that gets ugly to read.
I'd prefer to have a unique prefix* similar to .NET namespaces. It's better for organization, easier on the eye and works with tab completion. And it expands gracefully so you could name it DW.Get-Server or DW.Network.Get-Server.
The downside of doing this is it runs afoul of PowerShell's proper verb check during module import/Export-ModuleMember. You can get around this by specifying DisableNameChecking during import but I'm wondering if doing this is sloppy and might be bad if PowerShell 3 comes out with a better solution. I know PS verb purists (are there any?) will complain that this probably 'hinders discovery' but I can't think of a better option.
What do you do?
(*You can refer to an exported function using module_name\function_name notation but this won't work with tab completion and still doesn't get around the problem of the function name being unique).
I have heard Jeffrey Snover (the inventor of PowerShell) talk about this a few times and he described it as a dilemma, not a problem. A dilemma has to be managed but can't be solved completely. A problem can be solved. As a PS verb "purist" I would say the best way to manage this is to have a 2 or 3 letter prefix to your nouns. This has been sufficient so far for many widely distributed sets of cmdlets. IE, Quest AD Cmdlets vs Microsoft's AD Cmdlets. Get-ADUser and get-qaduser.
If you are consuming a module and want to use your own prefix, you can specify one with
import-module mymodule -Prefix myPrefix
I know this isn't the one single silver bullet answer, but I would say it works for 95% of the situations.

How can I control an interactive Unix application programmatically through Perl?

I have inherited a 20-year-old interactive command-line unix application that is no longer supported by its vendor. We need to automate some tasks in this application.
The most troublesome of these is creating thousands of new records with slightly different parameters (e.g. different identifiers, different names). The records have to be created in sequence, one at a time, which would take many months (and therefore dollars) to do manually. In most cases, creating a record has a very predictable pattern of keying in commands, reading responses, keying in further commands, etc. However, some record creation operations will result in error conditions ('record with this identifier already exists') that require a different set of commands to be exit gracefully.
I can see a few different ways to do this:
Named pipes. Write a Perl script that runs the target application with STDIN and STDOUT set to named pipes then sends the target application the sequence of commands to create a record with the required parameters, and then instructs the target application to exit and shut down. We then run the script as many times as required with different parameters.
Application. Find another Unix tool that can be used to script interactive programs. The only ones I have been able to find though are expect, but this does not seem top be maintained; and chat, which I recall from ages ago, and which seems to do more-or-less what I want, but appears to be only for controlling modems.
One more potential complication: I think the target application was written for a VT100 terminal and it uses some sort of escape sequences to do things like provide highlighting.
My question is what approach should I take? One of these, or something completely different? I quite like the idea of using named pipes and then having a Perl script that opens the FIFOs and reads and writes as required, as it provides a lot of flexibility, but from what I have read it seems like there's a lot of potential problems if I go down this path.
Thanks in advance.
I'd definitely stick to Perl for the extra flexibility, as chaos suggested. Are you aware of the Expect perl module? It's a lot nicer than the named pipe approach.
Note also with named pipes, you can't force the output coming back from your legacy application to be unbuffered, which could be annoying. I think Expect.pm uses pseudo-ttys to get around this problem, but I'm not sure. See the discussion in perlipc in the section "Bidirectional Communication with Another Process" for more details.
expect is a lot more solid than you're probably giving it credit for, but if I were you I'd still go with the Perl option, wanting to have a full and familiar programming language for managing the process and having confidence that whatever weird issues arise, there will be ways of addressing them.
Expect, either with the Tcl or Perl implementations, would be my first attempt. If you are seeing odd sequences in the output because it's doing odd terminal things, just filter those from the output before you do your matching.
With named pipes, you're going to end up reinventing Expect anyway.