Powershell: Failing to resume bitlocker remotely with script - windows

I am trying to resume BitLocker protection on remote devices. See the below code:
$computers = Get-Content "C:\Users\admin_jr\Documents\bitlockerlist.txt"
$credentials = Get-Credential
foreach($computer in $computers) {
Try {
$Session = New-PSSession $computer -Credential $credentials
if (-Not ($Session)) {
Write-Error "No session is made with the specified computer, please try again"
}
Invoke-Command -Session $Session -ScriptBlock {Get-BitLockerVolume | Resume-BitLocker -Verbose}
} Catch {
Write-Error "Something went wrong"
}
}
I get the following error message:
The TPM returned an unexpected result. (Exception from HRESULT: 0x8029010C)
+ CategoryInfo : NotSpecified: (:) [Write-Error], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException,Resume-BitLocker
+ PSComputerName : *pcname*
I am currently testing this on a laptop whereby I can manually resume and suspend the Bitlocker protection but essentially want to emulate and automate this via a script on multiple pcs.
Any advice on this?

Related

problem in windows powershell while installing haskell

I try to install haskell in my windows machine, I followed the instructions given in the website of haskell.org, but when I execute in the powerShell as an administrator this commande:
Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; try { Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $true } catch { Write-Error $_ }
It doesn't work and the terminal prints this message when the installation begins:
Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol =
[System.Net.ServicePointManager]::SecurityProtocol -bor 3072; try { Invoke-Command -ScriptBlock
([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing)))
-ArgumentList $true } catch { Write-Error $_ } : Exec: Error executing command curl.exe with arguments '-o
C:\Users\MBI\AppData\Local\Temp\\msys2-base-x86_64-20221216.sfx.exe
https://repo.msys2.org/distrib/x86_64/msys2-base-x86_64-20221216.sfx.exe'
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
can you help me I don't know what is the problem

appcmd.exe set config doesn't check if username or password is invalid and sets it anyways

I'm using winexe from my backend api to run commands on Windows Domain Server. I want to set IIS App Pool Identity as an Account from Active Directory. The problem is that while using this command :
%windir%\system32\inetsrv\appcmd.exe set config /section:applicationPools ^
/[name='POOLNAME'].processModel.identityType:SpecificUser ^
/[name='POOLNAME'].processModel.userName:DOMAIN\USER ^
/[name='POOLNAME'].processModel.password:PASSWORD
It runs successfully everytime even if the username and password is incorrect. Even the pool gets Started with wrong password. However setting wrong password through GUI fails.
I want to identify when the password or username is being set wrongly.
PS: I even tried using Set-ItemProperty on powershell and the result was the same.
You can't test your credentials with AppPool, but you can definitely test them.
# Service Principal credentials
$username = 'Username'
$password = 'Password' | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object -TypeName 'System.Management.Automation.PSCredential' -ArgumentList $username, $password
if (Test-Credential -Credential $credential) {
Write-Verbose "Credentials for $($credential.UserName) are valid..."
# do the appcmd stuff
}
else {
Write-Warning 'Credentials are not valid or some other logic'
}
Just add Test-Credential function definition at the top of your script
function Test-Credential {
[CmdletBinding()]
Param
(
# Specifies the user account credentials to use when performing this task.
[Parameter()]
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$DS = $null
$Username = $Credential.UserName
$SplitUser = $Username.Split('\')
if ($SplitUser.Count -eq 2 ) {$Username = $SplitUser[1]}
if ($SplitUser.Count -eq 1 -or $SplitUser[0] -eq $env:COMPUTERNAME ) {
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('machine', $env:COMPUTERNAME)
}
else {
try {
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('domain')
}
catch {
return $false
}
}
$DS.ValidateCredentials($Username, $Credential.GetNetworkCredential().Password)
}
(PS: Code is valid even though prettifier break with backslash quote syntax)
amazingly i puzzled out that you can do it like this - but it still doesn't validate
appcmd set apppool junkapp /processmodel.password:junkpassword

Powershell Delete Profile script - error checking not working

I have this delete profile script that prompts for a username and deletes it from each of the computers listed. The delete profile and "user is logged in" parts are both working but the part that says “No profiles found on $Computer with Name $UserName” is not. I ran my script on two computers and it successfully deleted my profile on both. I recreated my profile (logged in) and stayed logged on to one and not the other. I run it again and it gives me the message "user is logged in". For the other computer it just deleted the profile on does not display the "no profile found" message. It just skips over it and displays nothing. I have changed the "if" to an "else" but, when I do that it displays multiple lines of "no profiles found" including the computer it previously deleted the profile on.
Here is the link where most of the script is derived from.
http://techibee.com/powershell/powershell-script-to-delete-windows-user-profiles-on-windows-7windows-2008-r2/1556. Looking through the comments, no one else seemed to have any issues with that part of it.
I do not have much knowledge in PowerShell and this has just been pieced together from other scripts I have found based on our needs. Our environment is Windows 7 and Server 2008 R2. Any assistance is greatly appreciated.
$UserName=Read-host "Please Enter Username: "
$ComputerName= #("computer1","computer2")
foreach($Computer in $ComputerName) {
Write-Verbose "Working on $Computer"
if(Test-Connection -ComputerName $Computer -Count 1 -ea 0) {
$Profiles = Get-WmiObject -Class Win32_UserProfile -Computer $Computer -ea 0
foreach ($profile in $profiles) {
$objSID = New-Object System.Security.Principal.SecurityIdentifier($profile.sid)
$objuser = $objsid.Translate([System.Security.Principal.NTAccount])
$profilename = $objuser.value.split("\")[1]
if($profilename -eq $UserName) {
$profilefound = $true
try {
$profile.delete()
Write-Host -ForegroundColor Green "$UserName profile deleted successfully on $Computer"
} catch {
Write-Host -ForegroundColor Yellow "Failed to delete the profile, $UserName logged on to $Computer"
}
}
}
if(!$profilefound) {
Write-Host -ForegroundColor Cyan "No profiles found on $Computer with Name $UserName"
}
} else {
write-verbose "$Computer Not reachable"
}
}
PowerShell has a number of automatic variables that you should avoid re-using.
$Profile is one of these, it contains the paths to the Profile scripts applicable to the current session.
Use any other variable name (ie. $userprofile) and you'll be fine:
foreach ($userprofile in $profiles) {
$objSID = New-Object System.Security.Principal.SecurityIdentifier($userprofile.sid)
$objuser = $objsid.Translate([System.Security.Principal.NTAccount])
$profilename = $objuser.value.split("\")[1]
if($profilename -eq $UserName) {
$profilefound = $true
try {
$userprofile.delete()
Write-Host -ForegroundColor Green "$UserName profile deleted successfully on $Computer"
} catch {
Write-Host -ForegroundColor Yellow "Failed to delete the profile, $UserName logged on to $Computer"
}
}
}
I was able to get it working by changing the "$profilefound=$false" and making it a global variable. Also the reason why it was displaying multiple lines of "profile not found when i changed it to an else statement is because of where it was placed. It was checking against every profile on the server. When it touched every profile on the computer it displayed "profile not found".
Here is the working script.
$UserName=Read-host "Please Enter Username: "
$ComputerName= #("computer1","computer2")
$profilefound = "false"
foreach($Computer in $ComputerName) {
Write-Verbose "Working on $Computer"
if(Test-Connection -ComputerName $Computer -Count 1 -ea 0) {
$Profiles = Get-WmiObject -Class Win32_UserProfile -Computer $Computer -ea 0
foreach($userprofile in $profiles){
$objSID = New-Object System.Security.Principal.SecurityIdentifier($userprofile.sid)
$objuser = $objsid.Translate([System.Security.Principal.NTAccount])
$profilename = $objuser.value.split("\")[1]
if($profilename -eq $UserName) {
$profilefound = "true"
try {
$userprofile.delete()
Write-Host -ForegroundColor Green "$UserName profile deleted successfully on $Computer"
} catch {
Write-Host -ForegroundColor Yellow "Failed to delete the profile, $UserName logged on to $Computer"
}
}
}
}
else {
write-verbose "$Computer Not reachable"
}
if ($profilefound -eq "false") {
Write-Host -ForegroundColor Cyan "No profiles found on $Computer with Name $UserName"
}
}

Remote AD session error trapping woes

I am trying to catch exceptions in my remote PoSH script and I'm getting different behaviour depending on whether it is a local or remote PoSH session. The first code works as expected, the user cannot be enabled because it has no password and thus is caught by the ADPasswordComplexityException catch.
import-module activedirectory
try { Set-ADUser user123 -ErrorAction "stop" -Enabled $true }
catch [Microsoft.ActiveDirectory.Management.ADPasswordComplexityException] { write-host "gotya" }
catch { write-host "err" }
..resulting in gotya being written. This happens whether I run the code locally on the DC or another PC. So all good there.
However when doing this via a remote session not only the initial catch does not work, neither does the second catch..
$ADS = New-PSSession -computername dc.domain -Authentication default -Credential $(get-credential)
Import-Module ActiveDirectory -PSSession $ADS
try { Set-ADUser user123 -ErrorAction "stop" -Enabled $true }
catch [Microsoft.ActiveDirectory.Management.ADPasswordComplexityException] { write-host "gotya" }
catch { write-host "err" }
When run remotely it returns (presumably skipping all catches):
The password does not meet the length, complexity, or history requirement of the domain.
+ CategoryInfo : InvalidData: (user123:ADUser) [Set-ADUser], ADPasswordComplexityException
+ FullyQualifiedErrorId : The password does not meet the length, complexity, or history requirement of the etc..
Also when I run the remote script locally on the DC oddly I get a different error:
Unable to find type [Microsoft.ActiveDirectory.Management.ADPasswordComplexityException]: make sure that the assembly
containing this type is loaded.
At line:1 char:7
+ try { Set-ADUser -ErrorAction "stop" user123 -Enabled $true }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (Microsoft.Activ...lexityException:TypeName) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
Any ideas why PoSH hates me? thanks in advance.

How to implement a password change check in Powershell?

I've created a set of virtual machines (Windows Server) with a specific admin password; these VMs have been assigned to users, and may be in use. I want to know if the user changed the admin password, and do the check so the user doesn't notice. What are good solutions in powershell?
You could create a PSCredential, then attempt to get a WmiObject from the host. Something like:
$computerNames = "host1", "host2"
$pw = ConvertTo-SecureString "adminpw" -AsPlainText -Force
foreach($computerName in $computerNames)
{
$cred = New-Object System.Management.Automation.PSCredential("$computerName\Administrator", $pw)
try
{
Get-WmiObject win32_bios -ComputerName $computerName -Credential $cred
Write-Host "$computerName = Password not changed."
}
catch [System.UnauthorizedAccessException]
{
Write-Host "$computerName = Password changed."
}
}

Resources