Remotely Enable Wakeup from Shutdown - powershell

I am trying to get 400 pcs setup to wake on lan.
everything is enabled on all the pcs but one check box.
Under the advanced tab on the nic, "wakeup from Shutdown" is disabled
and I need to enable it on all pcs.
I have a working script to change the boxes under the power management tab but those are already checked. but I cant seem to find any info about anything under the advanced tab. properties on nic, configure, advanced)
Any help in figuring out if this is possible would be a big help.
Could I edit that code to just enable what I need? or simpler to write a new one?
I haven't tried anything cause I cant seem to find any info as to if this is even possible.
im thinking its just a different wmi object (probably wrong name) but in my code that works I found the lines that go to each check box and am wondering if there is a class for "wakeup from shutdown"
*** line im curious about
foreach ($NIC in $NICs) {
$Errors = $false
Write-Host "NIC:"$NIC.Name
#Allow the computer to turn off this device
Write-Host "Allow the computer to turn off this device....." -NoNewline
***$NICPowerManage = Get-WmiObject MSPower_DeviceEnable -Namespace root\wmi | Where-Object { $_.instancename -match [regex]::escape ($nic.PNPDeviceID) }
If ($NICPowerManage.Enable -ne $TurnOffDevice) {
$NICPowerManage.Enable = $TurnOffDevice
$HideOutput = $NICPowerManage.psbase.Put()
}
If ($NICPowerManage.Enable -eq $TurnOffDevice) {
Write-Host "Success" -ForegroundColor Yellow
} else {
Write-Host "Failed" -ForegroundColor Red
$Errors = $true
OTHER LINES
Get-WmiObject MSNdis_DeviceWakeOnMagicPacketOnly -Namespace root\wmi | Where-Object { $_.instancename -match [regex]::escape($nic.PNPDeviceID) }

I use this little tool called WMIExplorer.exe to navigate WMI. I think MSPower_DeviceWakeEnable is the class you are looking for.
After a few searches, I stumbled upon this. Perhaps that is similar to your problem.
https://www.itinsights.org/Enable-wake-on-lan-WOL-with-PowerShell/

Related

PowerShell Test-Connection is returning that a device is down when it is not

I am using the following code in PowerShell to ping multiple devices and return whether they are up or down.
$Output= #()
$names = Get-content "C:\HHM\hnames.txt"
foreach ($name in $names){
if (Test-Connection -ComputerName $name -Count 4 -Delay 2 -ErrorAction SilentlyContinue){
$Output+= "$name,up"
Write-Host "$Name,up"
}
else{
$Output+= "$name,down"
Write-Host "$Name,down"
}
}
$Output | Out-file "C:\HHM\result.csv"
When I check some of the devices that are listed as down, they are actually up. Given the nature of these devices, I do not believe that the connection is intermittent and the connection was actually down when the code was run. Would any of the other Test-Connection Parameters potentially help this? I've already used Count 4 and Delay 2, but I'm not sure if any of the other parameters will solve the issue.
EDIT - Just to clarify, I am getting the correct up/down status most of the time. Every once and a while, the code will return that a device is down, but when I go to check the device, I have a connection.
This may not be your problem, but you didn't specify if the devices have a static IP or dynamic IP. If dynamic, I would suggest always running ipconfig /flushdns prior to running your script. I can not begin to tell you how many times I thought a device was down, or thought I was connecting to one device only to discover I was connecting to another device.

Using PowerShell to identify a machine as a server or PC

I'm trying to write a PowerShell script that will give me a list if of roles and features if run on a server but if run on a client machine will say "Only able to execute command on a server."
I've played around with this script a lot and can get it to run on either a client machine or server (depending on what I've tweaked) but not both. Here's the latest iteration:
$MyOS="wmic os get Caption"
if("$MyOS -contains *Server*") {
Get-WindowsFeature | Where-Object {$_. installstate -eq "installed"
}}else{
echo "Only able to execute command on a server."}
What am I doing wrong?
The quotes around your wmic command will create the $MyOS variable with a String and not execute the command. Still, I would recommend you use native PowerShell commands such as Get-CimInstance. Like the $MyOS variable your if statement condition will always equal true as the quotes will make it a String.
$MyOS = Get-CimInstance Win32_OperatingSystem
if ($MyOS.Caption -like "*Server*") {
Get-WindowsFeature | Where-Object { $_. installstate -eq "installed" }
}
else {
Write-Output "Only able to execute command on a server."
}
You can also use the ProductType property. This is a (UInt32) number with the following values:
1 - Work Station
2 - Domain Controller
3 - Server
$MyOS = (Get-CimInstance Win32_OperatingSystem).ProductType
if ($MyOS -gt 1) {
Get-WindowsFeature | Where-Object { $_. InstallState -eq "installed" }
}
else {
Write-Output "Only able to execute command on a server."
}
Try to use '-like' instead of 'contains', it should work
Generally, I try to avoid pre-checks like this that make assumptions about functionality that may not be true forever. There's no guarantee that Get-WindowsFeature won't start working on client OSes in a future update.
I prefer to just trap errors and proceed accordingly. Unfortunately, this particular command produces a generic Exception rather than a more specifically typed exception. So you can't really do much other than string matching on the error message to verify specifically what happened. But there's very little that can go wrong with this command other than the client OS error. So it's pretty safe to just assume what went wrong if it throws the exception.
try {
Get-WindowsFeature | Where-Object { $_. InstallState -eq "installed" }
} catch {
Write-Warning "Only able to execute command on a server."
}
If you don't want to accidentally hide an error that's not the client OS one, change the warning message to just use the actual text from the error. This also gets you free localization if you happen to be running this code in a location with a different language than your own.
Write-Warning $_.Exception.Message

Passing active Powershell PSSession connection as argument in Start-Job

I am writing a script which gathers data from Exchange Online concerning mailbox permissions for each mailbox in our organization. To do this I gather all mailbox data into a variable then I use foreach to iterate through each mailbox and check the mailbox permissions applied to it. This takes time when you are working with over 15000 mailboxes.
I would like to use Powershell Jobs to speed this process up by having multiple jobs checking permissions and appending them to a single CSV file. Is there a way to pass an active PSSession into a new job so that the job "shares" the active session of the parent process that spawned the job and does not require a new one to be established?
I could place a New-PSSession call into the function but Microsoft has active session limits in Exchange Online PSSessions so it would limit the number of jobs I could have running at one time to 3. The rest would have to be queued through a while loop. If I can share a single session between multiple jobs I would be limited by computer resources rather than connection restrictions.
Has anyone successfully passed an active PSSession through to a job before?
Edit:
I've been working on using runspaces to try to accomplish this with Boe Prox's PoshRSJobs module. Still having some difficulty getting it to work properly. Doesn't create the CSV or append to it but only if I try to sort out the permissions within the foreach statement. The Write-Output inside the scriptblock only outputs the implicit remoting information too which is odd.
Code is below.
Connect-ToOffice365TenantPSSession
$mailboxes = Get-Mailbox -ResultSize 10 -IncludeInactiveMailbox
$indexCount = 1
foreach ($mailbox in $mailboxes) {
$script = #"
`$cred = Import-Clixml -Path 'C:\Users\Foo\.credentials\StoredLocalCreds.xml'
`$o365Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential `$cred -Authentication Basic -AllowRedirection
Import-PSSession `$o365Session -CommandName #('Get-Mailbox','Get-MailboxPermission')
`$internal_mailbox = `$Using:mailbox
`$mailboxPermissions = `$internal_mailbox | Get-MailboxPermission
foreach (`$permission in (`$mailboxPermissions | Where-Object {`$_.User -match 'tenantName|companyDomain'}))
{
`$userPermissions = `$permission | Select-Object Identity, User, AccessRights
`$permissionObject = [PSCustomObject]#{
"MailboxName" = `$userPermissions.Identity
"MailboxAddress" = `$internal_mailbox.PrimarySmtpAddress
"MailboxType" = `$internal_mailbox.RecipientTypeDetails
"UserWithAccess" = `$userPermissions.User
"AccessRights" = `$userPermissions.AccessRights
}
if (Test-Path 'C:\Scripts\MailboxPermissions.csv') {
`$permissionObject | Export-Csv 'C:\Scripts\MailboxPermissions.csv' -NoTypeInformation -Append
} else {
New-Item -Path 'C:\Scripts\MailboxPermissions.csv'
`$permissionObject | Export-Csv 'C:\Scripts\MailboxPermissions.csv' -NoTypeInformation -Append
}
Write-Output `$permissionObject
}
"#
$scriptBlock = [scriptblock]::Create($script)
$continue = $false
do
{
if ((Get-RSJob | Where-Object {$_.State -eq "Running"}).count -lt 3) {
Start-RSJob -Name "Mailbox $indexCount" -ScriptBlock $scriptBlock
$indexCount++
$continue = $true
}
else {
Start-Sleep 1
}
} while ($continue -eq $false)
}
Get-RSJob | Receive-RSJob
Thanks for the suggestions.
You have specifications here, but you are not showing code and yet, asking for an opinion.
That is, as many would say here, off topic, because the goal here is to assist with code that is not working or the like. So, at this point, have you tried what you are asking, and if so, what happened?
So, IMHO … Yet, since you are here. let's not send you away empty handed.
As per a similar ask here, the accepted answer delivered was...
… you have a current PSSession opened up on your console and then you
are attempting to use that same session in a background job. This will
not work because you are using two different PowerShell processes and
are unable to share the live data between the runspaces as it is
deserialized and loses all of its capabilities. You will need to look
at creating your own PowerShell runspaces if your goal is to share
live variables across multiple PowerShell sessions.
Even with the above, you still have those consumption limits you mention and technically based on your use case, you'd more than likely end up with serious performance issues as well.

Need a Way to Test a user against remote server using Powershell

My only objective is to validate the user account against bunch servers. I am using below commands to do it.
$creds2= Get-Credential
$servers = Get-Content ('C:\Users\vishnuvardhan.chapal\Documents\Widnows Servers success in 139 and 445.txt')
$servers | ForEach-Object {Get-WmiObject Win32_ComputerSystem -ComputerName $_ -Credential $creds2} | Out-GridView
Here, I am encountering two problems.
1) In the Grid view, I am just getting the hostname but without FQDN like shown in below screenshot.
2) Above screen is only for succeeded servers and for failed ones (for the servers, where authentication is failing) I am getting the output in Powershell window like below screen.
Now, my goal is to combine both the output's in at single place. Is it possible? If yes, How to do it? Please shed some light to it.
Apart from above is there any way to test it more easily, i mean a direct command to test the user authentication against a remote server??
FYI...My only goal for this exercise is to validate user authentication not to get some details from a remote computer.
Out-GridView is not a good way to handle these things. Recommended to convert that into JSON or some kind of a format and then parse it in files or however you wish to.
There are multiple ways to check that but error handling will solve your issue:
try
{
$creds2= Get-Credential
$servers = Get-Content ('C:\Users\vishnuvardhan.chapal\Documents\Widnows Servers success in 139 and 445.txt')
$servers
foreach($server in $servers)
{
try
{
Get-WmiObject Win32_ComputerSystem -ComputerName $Server -Credential $creds2
}
catch
{
"Error in accessing the server - $Server with the given credential. Kindly validate."
}
}
}
catch
{
$_.Exception.Message
}
So within the loop also I have added a try catch because if one server is failing, it will proceed with the next server from the list and that will capture the error with server name along with the message.
Hope it helps.

PowerShell Script to pop up at logoff

I have a basic understanding of PowerShell.
I would like to get my hands on a PowerShell script that will run at logoff.
This script needs to warn a user that their USB storage device is still plugged in before they sign out and they have to acknowledge the fact that it is and then select ok and then proceed to sign out
I know that the script needs to placed in an accessible location with the correct permissions and that a GPO can be used to enforce this. The script part is what I need help with..
If anyone out there in the interwebs please help?
Environment OS: Windows 10
AD not in use. Novell system used.
After you checked out what Franco stated, you can try something like the following. But still need to figure out how to make it work properly:
$usbs = GET-WMIOBJECT win32_diskdrive | Where { $_.InterfaceType –eq ‘USB’ }
$devices = #()
foreach($usb in $usbs){
$devices += $usb.Model + ". "
}
$input = [System.Windows.MessageBox]::Show("There are USB devices connected, $($devices | Out-String) Would you like to proceed logging off?","Warning","YesNoCancel","Error")
if($input -eq "Yes"){
shutdown -L
}elseif($input -eq "No"){
shutdown -A
}else{
break
}
You will need to find a way to make the user input visible before the logoff screen.