Looking for help on completing this Wsus script if possible - powershell

Edited for clarification: The goal is outlined in what I would like to accomplish. Now I don't know if I am headed in the right direction with this. So in a nut shell,
Am I going about this correctly? (example Is this single script possible or do I need multiple scripts? Is there a better process to doing this in powershell?)
How do I achieve my goal with what I have here? It only does part of what I am looking for. The part to list the computers an update should go out to and the status of the update on said computer I am struggling with.
I am not expecting people to write this but help me figure it out. I can't imagine I am the first one to fit these needs, but just haven't found a similar script for assistance.
Backstory:
For the last few weeks I have been teaching myself Powershell to accomplish a wsus reporting goal. I have searched everywhere trying to find a script that I could modify to fit my needs but I feel my limited skills is making that difficult.
Goal: Pre-approval
I am trying to generate a list of updates that are needing to be approved. (This works) But for each update I want to list out the servers who should be getting this update along with the update status. Example: Update KB12345 is needed by server1/server2/server3 and install status equals X. I am just confused as to the best way to handle this. I am ok with exporting to different file formats. TXT for the first part that lists "How many updates need to be approved" and excel for the computer status part. I started playing with computerscope but I was not able to filter it so I can get workstations vs servers. It lists everything all together.
Goal: Verify Installed status
I would like to run a second check against this during/after our maint window so we can confirm everything installed correctly and that report is logged in our change request for audit needs.
Things I have tried:
Checking each computer to see if the update was installed using a different script took way to long and was dependent on the workstation being available. Servers not so much a big deal as they are always up. Servers we can compare against locally if wsus doesn't get updated in time, but I would need to be able to run this so that I can report on the workstations for this month. (I only care about the updates being applied per month. Not outstanding or previous updates.)
I thought about splitting up this into two scripts. One that did the approval list and one that is run after comparing against a list of KB#s in a text file.
I feel this is a bit overkill but in how our SOX auditing this year has been any hiccup or concern was crazy scrutinized.
#Note the "Cleanup" in my script is a local function to ISEprofile that clears everything on each run. This is removed when it is put into production.
Cleanup
[void][reflection.assembly]::LoadWithPartialName(“Microsoft.UpdateServices.Administration”)
#Connect to the WSUS Server and create the wsus object
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer(‘wsus’,$False,"8530")
#Variables
#Wsus Variables
$Arrivaldate = ”01/12/2021"
#ApprovedStatus could be the following:Any, declined, hasstaleupdateapprovals, latestrevisionapproved, notapproved
$ApprovedStatus = "notapproved"
$InstallationStatus = "NotInstalled"
#Logging Variables
$Logpath = "D:\scripts\ps1\Testing\Logs\Monthlyupdatelist.txt"
#Create a computer scope object
$computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
#Create UpdateScope
$updatescope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
#Find all clients using the computer target scope
#$wsus.GetComputerTargets($computerscope)
#$Wsus.GetComputerStatus($computerscope,[ Microsoft.UpdateServices.Administration.UpdateSources]::All)
#Find updates based on scope below. Run $updatescope alone to see all the items you can filter by.
$updatescope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::$ApprovedStatus
$updatescope.IncludedInstallationStates = [Microsoft.UpdateServices.Administration.UpdateInstallationStates]::$InstallationStatus
$updatescope.FromArrivalDate = [datetime]$Arrivaldate
Start-Transcript -Path $Logpath
#This lists how many updates are set in "all updates"
Write-Host "Number of Updates this month to approve:"$wsus.GetUpdateCount($updatescope)
$wsus.GetUpdateStatus($updatescope,$False)
#List out the updates for the month
$Updatelist = $wsus.GetUpdates($updatescope)
$Updatelist | Select Title, UpdateClassificationTitle, KnowledgebaseArticles, ProductTitles, ArrivalDate, IsApproved, IsDeclined
Stop-Transcript

Related

Get Skype for Business User Status/Availability issue in Powershell

I'm using powershell to get the Status/Availability of certain users by using the following code:
Import-Module "C:\...\Microsoft.Lync.Model.dll"
$Client = [Microsoft.Lync.Model.LyncClient]::GetClient()
$Contact = $Client.ContactManager.GetContactByUri( $args[0] )
Write-Host $Contact.GetContactInformation("Activity")
Let's say I'm passing in testuser#testcompany.com as the script argument.
If I run this script, it will return "Presence unknown". However, if I open up the Skype client manually and search for the user, I can see their availability then (let's say this user is set to Available).
Now, if I run my script again now after I've searched for them in Skype, the script will return the proper result by printing "Available" to the console. The script will continuously return the proper result until I restart Skype. At the point, it will return "Presence unknown" again until I search for the user in Skype.
If the user is in my Recent Conversations in Skype and I simply view my Recent Conversations tab rather than searching for them, that is enough to have the script start returning the proper result.
It would appear as though it is unable to query their availability until it is manually loaded into cache(?) from my client. Any idea why this would possibly happen or how I can have it return the proper results without manually searching for the user first?
Only workaround I have found is to create a conversation with the target user like this:
Import-Module "Microsoft.Lync.Model.dll"
$client = [Microsoft.Lync.Model.LyncClient]::GetClient()
$contact = $client.ContactManager.GetContactByUri($email)
$convo = $client.ConversationManager.AddConversation()
$convo.AddParticipant($contact) | Out-Null
Write-Host $contact.GetContactInformation("Activity")
$convo.End() | Out-Null
It doesn't appear to cause any IM windows to popup on the users side.
It would be interesting to see your powershell code for the subscription solution
Looks like you have to subscribe to user presence information. Lync SDK MSDN documentation has outlined the solution at https://msdn.microsoft.com/en-us/library/office/jj937284.aspx.
Similar solution at https://social.msdn.microsoft.com/Forums/en-US/12357db7-769f-4808-bc99-9b2fb2ed8ce2/presence-unknown?forum=communicatorsdk

Can I enable / Disable an Azure Service Bus Topic using Powershell

I have spent a couple of hours search for a solution to disable my Azure Service Bus Topics using Powershell.
The background for this is we want to force a manual failover to our other region.
Obviously I could click in the Portal:
but I want to have a script to do this.
Here is my current attempt:
Any help would be great.
Assuming you're sure your $topic contains the full description, modify the status parameter in the array and then splat it back using the UpdateTopic method. I'm afraid I can't test this at present.
$topic.Status = "Disabled"
$topicdesc = $NamespaceManager.UpdateTopic($topic)
I don't think you'll need to set the entity type for the Status, nor do you require semi-colons after each line of code in your loop.
References
PowerShell Service Bus creation sample script (which this appears to be based off): https://blogs.msdn.microsoft.com/paolos/2014/12/02/how-to-create-service-bus-queues-topics-and-subscriptions-using-a-powershell-script/
UpdateTopic method: https://msdn.microsoft.com/en-us/library/azure/microsoft.servicebus.namespacemanager.updatetopic.aspx
Additional note: please don't screenshot the code - paste it in. I'd rather copy-and-paste than type things out.

How do you unlock an Active Directory account on a different domain using PowerShell 2.0?

I found an amazing PowerShell script by LazyWinAdmin that kind of does what I want - but it is limited to just the current domain. The way our network is set up we have different domains for certain types of accounts.
I am trying to write up a script that simply unlocks a specified user account on a specific domain. Our system uses PowerShell 2.0 which is making this very difficult because I know that the later versions have Active Directory management cmdlets. Trust me, I have requested that we have a newer version of PowerShell installed on our systems but the company flat out refuses to budge.
I feel kind of stupid because I have worked almost exclusively with the newer versions in the past so I got used to the various cmdlets rather than having to manually draft out every single thing I want to do.
You need to specify the search root to search from other domain.
Original code in $buttonUnlock_Click:
# Search for this account in the current domain
$Searcher = [ADSISearcher]"(sAMAccountName=$Name)"
$Results = $Searcher.FindOne()
Also in $buttonCheck_Click (it has no search code but just a comment):
# Search for this account in the current domain
Change both to:
$searcher = New-Object DirectoryServices.DirectorySearcher
$searcher.Filter = "(sAMAccountName=$name)"
$searcher.SearchRoot = New-Object DirectoryServices.DirectoryEntry('LDAP://other.domain', 'user', 'pwd')
$results = $searcher.FindOne()
If current user already has permission to access the other domains, you may simply put [adsi]'LDAP://other.domain' as search root.

Error when re-declaring item as record via PowerShell - "The file has been modified "SHAREPOINT\system"

We have had a PowerShell script scheduled and executing successfully for the past 3-4 months (In both Test and Prod). The purpose of the script is to update document properties in SharePoint when certain triggers are fired from external systems. Without getting into too much detail, below is the code that has been used to update item properties for a document that has been declared a record:
$recordsmanagement=[Microsoft.Office.RecordsManagement.RecordsRepository.Records]
$recordsmanagement::UndeclareItemAsRecord($item)
$item = $list.GetItemById($item.id)
$item.File.CheckOut()
$item[$sSpFieldName]=$sDbValue
$item.Update()
$item = $list.GetItemById($item.id)
$item.File.CheckIn("")
$recordsmanagement::DeclareItemAsRecord($item)
This code has worked hundreds of times without a problem. For some reason, this code started bombing a week ago on the last line (when re-declaring as a record):
System.Management.Automation.MethodInvocationException: Exception calling "DeclareItemAsRecord" with "1" argument(s): "The file /lib/folder/file.pdf has been modified by SHAREPOINT\system on 10 Oct 2012 00:00:47 -0500."
The other weird part is that this is only happening in Prod. The Test environment seems to execute just fine. I haven't tried a fix for production yet, but I'm pretty sure I can just get the $item object again using GetItemById (after the CheckIn). I'm a little hesitant to do this just yet as I wanted to get some other people's perspective first.
Does anyone have any input on this? Thanks in advance.
I think the best bet is to get the item again after the checkin as you say.
The error message indicates exactly that. You are trying to perform an operation on a SPListItem that has been modified. So pull it again using GetItemById before you declare it as a record.
Why it only happens on some records and on some environment I am not sure. I guess Sharepoint is a bit temperamental.
Thing I would try as well:
Check if there is any workflow doing some work on that item when you check it in
Try to use SystemUpdate() instead of Update() if that suits your requirements
Good luck

Add a "Hyperlink" item type to a list using PowerShell in Sharepoint

I've been a SharePoint admin for a while, and now have been tasked with a bit more of a developer role - which I'm still very much learning. Most things I've been able to figure out on my own or through Google, but this one has me stumped.
For one particular task I need to use PowerShell to script adding items to a list. Normally - not a difficult task. These steps are all over the web. However, I have yet to find anywhere that will tell you how to add a "Hyperlink" type of item to a list.
I can add one using the following code:
$NewItem = $MyList.Items.Add()
$NewItem["My Hyperlink Column"] = $($url.url)
$NewItem.Update()
But I want to set the name/title of the link as well and that's what stumps me. I don't want to have to create a separate column in the list and populate that with the link name, and use code similar to above to populate the url/link.
Does this work for you? I don't have a Sharepoint install available to test on, this is from memory:
$NewItem = $MyList.Items.Add()
$NewItem["My Hyperlink Column"] = "$($url.url), <Title>"
$NewItem.Update()
james
Thanks James! That was very close and I'm thinking would work if I was specifying a single item?
Here's my full solution (with some extra bits):
$enumsite = new-object microsoft.sharepoint.spsite($SubWebUrl)
foreach ($url in $enumsite.allwebs)
{
$NewItem = $MyList.Items.Add()
$NewItem["My Hyperlink Column"] = "$($url.url), $(url.title)"
$NewItem.Update()
}
$enumsite.Dispose()
Perhaps this will help someone else out in the future.