add scripts to prevent family safety monitoring

This commit is contained in:
undergroundwires
2020-12-30 19:47:36 +01:00
parent 34672414c3
commit e14bf2bfa0
3 changed files with 176 additions and 72 deletions

View File

@@ -1267,6 +1267,32 @@ actions:
docs: https://www.tenforums.com/tutorials/4077-turn-off-sync-settings-microsoft-account-windows-10-a.html
code: reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\SettingSync\Groups\Language" /t REG_DWORD /v "Enabled" /d 0 /f
revertCode: reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\SettingSync\Groups\Language" /t REG_DWORD /v "Enabled" /d 1 /f
-
category: Prevent Microsoft family safety monitoring
children:
-
name: Disable Microsoft Family Safety Monitor
recommend: standard
code: |-
schtasks /change /disable /tn "Microsoft\Windows\Shell\FamilySafetyMonitor"
schtasks /change /disable /tn "Microsoft\Windows\Shell\FamilySafetyRefresh"
schtasks /change /disable /tn "Microsoft\Windows\Shell\FamilySafetyUpload"
revertCode: |-
schtasks /change /enable /tn "Microsoft\Windows\Shell\FamilySafetyMonitor"
schtasks /change /enable /tn "Microsoft\Windows\Shell\FamilySafetyRefresh"
schtasks /change /enable /tn "Microsoft\Windows\Shell\FamilySafetyUpload"
-
name: Uninstall Microsoft Family Safety Monitor
recommend: strict
call:
-
function: RenameSystemFile
parameters:
filePath: '%SystemRoot%\System32\WpcTok.exe'
-
function: RenameSystemFile
parameters:
filePath: '%SystemRoot%\System32\WpcMon.exe'
-
category: Configure programs
children:
@@ -4078,3 +4104,24 @@ functions:
parameters: [ capabilityName ]
code: PowerShell -Command "Get-WindowsCapability -Online -Name '{{ $capabilityName }}*'' | Remove-WindowsCapability -Online"
revertCode: PowerShell -Command "$capability = Get-WindowsCapability -Online -Name '{{ $capabilityName }}*''; Add-WindowsCapability -Name \"$capability.Name\" -Online"
-
name: RenameSystemFile
parameters: [ filePath ]
code: |-
if exist "{{ $filePath }}" (
takeown /f "{{ $filePath }}"
icacls "{{ $filePath }}" /grant administrators:F
move "{{ $filePath }}" "{{ $filePath }}.OLD"
echo Moved "{{ $filePath }}" to "{{ $filePath }}.OLD"
) else (
echo No action required: {{ $filePath }} is not found.
)
revertCode: |-
if exist "{{ $filePath }}.OLD" (
takeown /f "{{ $filePath }}.OLD"
icacls "{{ $filePath }}.OLD" /grant administrators:F
move "{{ $filePath }}.OLD" "{{ $filePath }}"
echo Moved "{{ $filePath }}.OLD" to "{{ $filePath }}"
) else (
echo Could not find backup file "{{ $filePath }}.OLD" 1>&2
)

View File

@@ -23,19 +23,19 @@ function validateCode(name: string, code: string): void {
if (!code || code.length === 0) {
throw new Error(`code of ${name} is empty or undefined`);
}
ensureCodeHasUniqueLines(name, code);
ensureNoEmptyLines(name, code);
ensureCodeHasUniqueLines(name, code);
}
function ensureNoEmptyLines(name: string, code: string): void {
if (code.split('\n').some((line) => line.trim().length === 0)) {
throw Error(`Script has empty lines "${name}"`);
throw Error(`script has empty lines "${name}"`);
}
}
function ensureCodeHasUniqueLines(name: string, code: string): void {
const lines = code.split('\n')
.filter((line) => mayBeUniqueLine(line));
.filter((line) => !shouldIgnoreLine(line));
if (lines.length === 0) {
return;
}
@@ -45,13 +45,13 @@ function ensureCodeHasUniqueLines(name: string, code: string): void {
}
}
function mayBeUniqueLine(codeLine: string): boolean {
const trimmed = codeLine.trim();
if (trimmed === ')' || trimmed === '(') { // "(" and ")" are used often in batch code
return false;
}
if (codeLine.startsWith(':: ') || codeLine.startsWith('REM ')) { // Is comment?
return false;
}
return true;
function shouldIgnoreLine(codeLine: string): boolean {
codeLine = codeLine.toLowerCase();
const isCommentLine = () => codeLine.startsWith(':: ') || codeLine.startsWith('rem ');
const consistsOfFrequentCommands = () => {
const frequentCodeParts = [ '(', ')', 'else' ];
const trimmed = codeLine.trim().split(' ');
return trimmed.every((part) => frequentCodeParts.includes(part));
};
return isCommentLine() || consistsOfFrequentCommands();
}

View File

@@ -1,6 +1,7 @@
import 'mocha';
import { expect } from 'chai';
import { ScriptCode } from '@/domain/ScriptCode';
import { IScriptCode } from '../../../src/domain/IScriptCode';
describe('ScriptCode', () => {
describe('scriptName', () => {
@@ -15,75 +16,131 @@ describe('ScriptCode', () => {
});
});
describe('code', () => {
it('cannot construct with duplicate lines', () => {
describe('throws with invalid code', () => {
// arrange
const code = 'duplicate\nduplicate\ntest\nduplicate';
// act
const act = () => createSut(code);
// assert
expect(act).to.throw();
const scriptName = 'test-script';
const testCases = [
{
name: 'throws when "execute" and "revert" are same',
code: {
execute: 'same',
revert: 'same',
},
expectedError: `${scriptName} (revert): Code itself and its reverting code cannot be the same`,
},
{
name: 'cannot construct with undefined "execute"',
code: {
execute: undefined,
revert: 'code',
},
expectedError: `code of ${scriptName} is empty or undefined`,
},
{
name: 'cannot construct with empty "execute"',
code: {
execute: '',
revert: 'code',
},
expectedError: `code of ${scriptName} is empty or undefined`,
},
];
for (const testCase of testCases) {
it(testCase.name, () => {
// act
const act = () => new ScriptCode(scriptName, testCase.code.execute, testCase.code.revert);
// assert
expect(act).to.throw(testCase.expectedError);
});
}
});
it('cannot construct with empty lines', () => {
describe('throws with invalid code in both "execute" or "revert"', () => {
// arrange
const code = 'line1\n\n\nline2';
const scriptName = 'script-name';
const testCases = [
{
testName: 'cannot construct with duplicate lines',
code: 'duplicate\nduplicate\ntest\nduplicate',
expectedMessage: 'Duplicates detected in script "$scriptName":\n duplicate\nduplicate',
},
{
testName: 'cannot construct with empty lines',
code: 'line1\n\n\nline2',
expectedMessage: 'script has empty lines "$scriptName"',
},
];
// act
const act = () => createSut(code);
const actions = [];
for (const testCase of testCases) {
const substituteScriptName = (name) => testCase.expectedMessage.replace('$scriptName', name);
actions.push(...[
{
act: () => new ScriptCode(scriptName, testCase.code, undefined),
testName: `execute: ${testCase.testName}`,
expectedMessage: substituteScriptName(scriptName),
},
{
act: () => new ScriptCode(scriptName, 'valid code', testCase.code),
testName: `revert: ${testCase.testName}`,
expectedMessage: substituteScriptName(`${scriptName} (revert)`),
},
]);
}
// assert
expect(act).to.throw();
for (const action of actions) {
it(action.testName, () => {
expect(action.act).to.throw(action.expectedMessage,
`Code used: ${action.code}`);
});
}
});
it('cannot construct with empty or undefined values', () => {
describe('sets as expected with valid "execute" or "revert"', () => {
// arrange
const name = 'test-code';
const errorMessage = `code of ${name} is empty or undefined`;
const invalidValues = [ '', undefined ];
invalidValues.forEach((invalidValue) => {
// act
const act = () => new ScriptCode(name, invalidValue, '');
// assert
expect(act).to.throw(errorMessage);
});
});
it('sets as expected', () => {
// arrange
const expected = 'expected-revert';
const testCases = [
{
testName: 'code is a valid string',
code: 'valid code',
},
{
testName: 'code consists of frequent code parts',
code: ') else (',
},
{
testName: 'code is a frequent code part',
code: ')',
},
{
testName: 'code with duplicated comment lines (::)',
code: ':: comment\n:: comment',
},
{
testName: 'code with duplicated comment lines (REM)',
code: 'REM comment\nREM comment',
},
];
// act
const sut = createSut(expected);
const actions = [];
for (const testCase of testCases) {
actions.push(...[
{
testName: `execute: ${testCase.testName}`,
act: () => createSut(testCase.code),
expect: (sut: IScriptCode) => sut.execute === testCase.code,
},
{
testName: `revert: ${testCase.testName}`,
act: () => createSut('different code', testCase.code),
expect: (sut: IScriptCode) => sut.revert === testCase.code,
},
]);
}
// assert
expect(sut.execute).to.equal(expected);
});
});
describe('revert', () => {
it('cannot construct with duplicate lines', () => {
// arrange
const code = 'duplicate\nduplicate\ntest\nduplicate';
// act
const act = () => createSut('REM', code);
// assert
expect(act).to.throw();
});
it('cannot construct with empty lines', () => {
// arrange
const code = 'line1\n\n\nline2';
// act
const act = () => createSut('REM', code);
// assert
expect(act).to.throw();
});
it('cannot construct with when same as code', () => {
// arrange
const code = 'REM';
// act
const act = () => createSut(code, code);
// assert
expect(act).to.throw();
});
it('sets as expected', () => {
// arrange
const expected = 'expected-revert';
// act
const sut = createSut('abc', expected);
// assert
expect(sut.revert).to.equal(expected);
for (const action of actions) {
it(action.testName, () => {
const sut = action.act();
expect(action.expect(sut));
});
}
});
});
});